Java文件IO常用归纳

我们常说的标准IO操作,包含了本篇所述的文件IO。我们知道,IO无非是输入输出,数据在动的时候以流形式存在(Byte or Bit 为单位),而在静的时候则以文件形式存在(因为我们知道文件就是若干Byte等单位的数据或数据集合)。

前言:关于文件的编码


  1. 在windows 下,eclipse等IDE的默认项目编码是GBKGBK编码:中文占用2byte,英文占用1byte。
  2. utf-8编码中:中文占用3byte,英文占用1byte。
  3. 如何把单个字节转换为int以16进制的方式显示:
String ch = "A";
byte[] bytes = ch.getBytes();
System.out.println(Integer.toHexString(bytes[0] & 0xff));///为了将变成int类型后(8bit->32bit)的值,除去前30位的值,只留下最低2位。
  1. Java是双字节编码(utf-16be),utf-16be编码:中文和英文都占用2byte。
  2. Java中字符串与字节序列之间的转换示例:
String str = "你好1234";
byte[] bytes = str.getBytes("utf-16be");
String str2 = new String(bytes, "utf-16be");
  1. 文本文件(.txt)就是字节序列(可以是任意编码的字节序列)
  2. 中文机器上(比如我们的PC)直接创建文本文件,那么该文件只认识ansi编码
  3. 创建的Java项目设定是utf-8编码,那么, 它创建的文本文件编码格式就是utf-8编码。将此文本文件拷贝到其他不是utf-8编码的项目目录下,就会乱码。但是将此文本文件拷贝到我们PC的任何其他目录下,都不会有乱码。(注意是拷贝,不是新建,这是由于:文本文件本身就是识别任意编码格式的字节序列)

Java IO示例与注意点


(一)File类

  1. 创建/获取文件对象,使用File.separator分隔符:
File file = new File("E:\\test");///一般windows下用(双斜杠)
//File file0 = new File("e:\\", "diary.txt");
File file2 = new File("E:/test");///一般linux和macos下用(反斜杠)
File file3 = new File("E:" + File.separator +"test");///系统间通用
  1. 创建的文件对象是一个多级目录时,需要File.mkdirs()而不是File.mkdir()
if(!file.exists())
    file.mkdirs();
  1. 打印File.toString(),默认打印文件的目录:
System.out.println(file);/// output: e://test

(二)文件读写IO

  1. 关于RandomAccessFile:RandomAccessFile类支持随机访问文件并可以访问文件的任意位置:read()write()就是这个类的其他方法的基础原理。
RandomAccessFile raf = new RandomAccessFile(file, "rw");//两个模式:rw表示读写,r表示只读。
raf.write(int);//只写一个字节(后8位),同时指针后移一个位置,准备再次写入。
int b = raf.read();//读一个字节
int max = 0x7ffffff;
raf.write(max>>>24);//最高8位
raf.write(max>>>16);//8位
raf.write(max>>>8);//8位
raf.write(max);///最低8位
  1. IO流基础
  • 分为:字节流、字符流
  • EOF = End:-1表示读到结尾
  • 字节流:InputStream、OutputStream(抽象类)【具体方法可以查看它的API文档】
    • 输入流最重要方法:
      int b = in.read();///读取一个字节无符号填充到int低8位。-1表示EOF
      in.read(byte[] buf);///读取内容到buf字节数组中
      in.read(byte[] buf , int start, int size);//读取内容的一小段,到buf
      
    • 输出流最重要方法:
      out.write(int b);///写出一个字节到流,b的低8位。
      out.write(byte[] buf);//将buf字节数组写入到流
      out.write(byte[] buf, int start, int size);///将将buf[start]开始的size长度内容写入。
      
    • 各种字节流实现类:
      • 【基本文件操作】FileInputStream/FileOutputStream:具体实现了在文件上存取byte数据的方法。
      • 【更多封装方法】DataInputStream/DataOutputStream:对“流”进行了扩展,可以更方面地读取int、long、字符等类型数据【相当于比FileInputStream等多了些封装方法(装饰模式)】
      DataOutputStream dos = new DataOutputStream(new FileOutputStream(file));
      dos.writeUTF("中国");//采用utf-8编码写出
      dos.writeChars("中国");//采用utf-16be编码写出
      
      • 【更高效率】BufferedInputStream/BufferedOutputStream:为流IO提供了带缓冲区的操作,一般打开文件进行IO操作时,都会用到,这种流模式提高IO性能。
  • 字符流
    • 注意编码问题
    • 文本与文本文件的区别:
      • Java的文本(char)是16位无符号整数(unsigned 16bit int),是字符的unicode编码(双字节编码)。
      • 文本文件是文本(char)序列按照某种方案(如:utf-8、utf-16be、gbk等)序列化为byte的存储结果。
    • 【基本实现】InputStreamReader/OutputStreamWriter:完成byte-->char的按编码解析/char-->byte的按编码处理
    InputStreamReader isr = new InputStreamReader(new FileInputStream(file));///默认使用项目的编码格式(非utf-16be)
    char[] chs = new char[1024];
    int len;
    while((len=isr.read(chs,0,chs.length))!=-1){
      String s = new String(chs,0,len);
      System.out.println(s);
    }
    
    • FileReader/FileWriter:可直接对文本文件进行字符流读写。在copy文件时,可覆盖或追加文件内容。不用byte转char,但是编码问题不能解决。
    • BufferedReader/BufferedWriter:带缓冲,(String line = br.readLine())!=null方法可以一次读一行,高效率,但不能识别换行。
    BufferedReader br = new BufferedReader(new InputStreamReader(
                                      newFileInputStream(file)));//读
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                                      newFileOutputStream(newFilePath)));//写
    String line;
    while((line = br.readLine())!=null){
      ///输出并写入新文件
      bw.write(line);
      bw.newLine();///单独写出换行操作!!!
      bw.flush;
    }
    br.close();
    bw.close();
    
    • PrintWriter:简单化构造一个写入流,换行操作很方面:println(str);

(三)对象读写 与 序列化

  1. 序列化:Object转byte序列的过程。
  2. 序列化流:ObjectOutputStream/ObjectInputStream,对于方法:writeObject()、readObject()
  3. JVM在对象内部调用的默认序列化方法:
///成员方法writeObject()
public void writeObject(ObjectOutputStream s) throws IOException{
  s.defaultWriteObject();
}
  1. 如果想要自己做某个元素的序列化操作:
public void writeObject(ObjectOutputStream s) throws IOException{
  s.defaultWriteObject();
  s.writeInt(age);///如这个age变量,就被我们自行序列化写入了
}
  1. Serializable接口是一个标准,是序列化的前提。
  2. transient关键字:被标注的成员不会被jvm进行默认序列化。【有时可以提高性能】
  3. ArrayList内部维护着Object[]类型的数组对象,这个对象是被transient修饰的,但是ArrayList并不是不想进行序列化操作,而是想自己去实现序列化的方式而不去给JVM默认进行序列化,这样一来即可提高效率。
  4. 序列化时:一个类实现了Serializable接口,其子类都能够被需序列化。
  5. 反序列化时:对子类对象进行反序列化,如果其父类没有实现Serializable接口,则其父类的构造方法会被调用。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容