IO流02
-
节点流和处理流
节点流可以从一个特定的数据源读写数据,如FileReader和FileWriter
处理流(包装流)在已存在的节点流进行包装,功能更强大。如BufferedReader、BufferedWriter,其类中包含一个Reader/Writer属性
BufferedReader和BufferedWriter是字符流,BufferedInputStream和BufferedOutputStream是字节流public static void main(String[] args) { String filePath = "d:\\a.txt"; BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(filePath)); String line; //返回为null时表示读取完毕 while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } } catch (IOException e) { throw new RuntimeException(e); } finally { try { bufferedReader.close(); } catch (IOException e) { throw new RuntimeException(e); } } }
-
对象流
ObjectInputStream和ObjectOutputStream
可以将基本数据类型或者对象进行序列化和反序列化
序列化就是在保存数据时,保存数据的值和数据类型
反序列化就是在恢复数据时,恢复数据的值和数据类型
为了使某个类可序列化,必须实现以下两个接口之一:Serializable或Externalizable。其中,Serializable为标记接口,其中没有任何方法public class Demo16 { public static void main(String[] args) { String filePath = "d:\\a.dat"; ObjectOutputStream oos = null; try { oos = new ObjectOutputStream(new FileOutputStream(filePath)); oos.writeInt(100); oos.writeBoolean(true); oos.writeChar('H'); oos.writeUTF("嗨嗨嗨"); oos.writeObject(new Dog("狗子", 5)); } catch (IOException e) { throw new RuntimeException(e); } finally { try { oos.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
反序列化class Dog implements Serializable { private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } }
注意在反序列化时,读取方必须能访问到Dog类的定义,而且如果想要访问Dog的方法,则当前文件需import Dog类,接受变量类型为Dog类对象public class Demo17 { public static void main(String[] args) { String filePath = "d:\\a.dat"; ObjectInputStream ois = null; try { ois = new ObjectInputStream(new FileInputStream(filePath)); //读取顺序需要与写入顺序一致 System.out.println(ois.readInt()); System.out.println(ois.readBoolean()); System.out.println(ois.readChar()); System.out.println(ois.readUTF()); Object o = null; try { o = ois.readObject(); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } System.out.println("类型=" + o.getClass()); System.out.println("dog信息=" + o); } catch (IOException e) { throw new RuntimeException(e); } finally { try { ois.close(); } catch (IOException e) { throw new RuntimeException(e); } } } }
注意事项- 读写顺序要一致
- 序列化或反序列化的对象,需要实现Serializable接口
- 序列化的类中建议添加SerialVersionUID,如
private static final long serialVersionUID = 1L;
则后续修改该类后,再序列化时会认定为对同一个类的版本迭代,而非新的类,提高兼容性 - 序列化对象时,默认将里面所有属性都进行序列化,但是static或transient修饰的成员除外,他们在序列化后的文件中不存在
- 序列化对象时,要求里面属性的类型也是可序列化的
- 序列化有可继承性,如果某类已经实现了序列化,则他的所有子类也默认实现了序列化
-
标准输入输出流
- 编译类型 运行类型 默认设备 System.in标准输入 InputStream BufferedInputStream 键盘 System.out标准输出 PrintStream PrintStream 显示器 -
转换流
InputStreamReader和OutputStreamReader,将字节流转为字符流,构造时可以指定字符集public static void main(String[] args) { String filePath = "a.txt"; InputStreamReader isr = null; BufferedReader br = null; try { isr = new InputStreamReader(new FileInputStream(filePath), "gbk"); br = new BufferedReader(isr); String s = br.readLine(); System.out.println(s); } catch (IOException e) { throw new RuntimeException(e); } finally { try { br.close(); } catch (IOException e) { throw new RuntimeException(e); } } }