1.什么是I/O
I/O: Java程序的输入/输出
Input: 从外部数据源中读取数据
Output:向外部数据源写出数据
2.什么是流
流: 用来传输数据的对象
按照数据方向: 输入流/输出流
按照数据单位: 字节流(处理一切数据)/字符流(处理文本数据)
按照流的功能: 节点流(实际完成数据传输)/过滤流(为节点流增强功能)
2.1字节流
类名 | 作用 | 常用方法 |
---|---|---|
InputStream/OutputStream | 所有字节流的父类 抽象类 | read()/write()/close() |
FileInputStream/FileOutputStream | 文件流 节点流 | |
BufferedInputStream/BufferedOutputStream | 缓冲流 | |
ObjectInputStream/ObjectOutputStream | 读/写对象 | readObject()<br/>writeObject() |
OutputStream fos = null;
try {
fos = new FileOutputStream("a.txt");
fos.write('A');
} catch (IOException e) {
e.printStackTrace();
}
finally{
try {
if (fos!= null) fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
上下两段代码功能一样,since JDK7,实现AutoCloseable接口的类都可以用 try-with-resources 结构,编译器会把下面的代码自动改写成上面的。
try(FileOutputStream fos = new FileOutputStream("a.txt")){
fos.write('A');
}
catch(IOException e){
e.printStackTrace();
}
2.1.1对象序列化
利用ObjectStream去传输对象
只有实现了Serializable接口的对象才能序列化
对象的属性如果又是一个对象,也需要可序列化.如果属性是个集合,就要求集合中的所有元素都是可序列化的
用transient关键字修饰的属性为临时属性,不参与序列化
补充内容
为了类的变化尽可能不影响反序列化的结果, 可以为类添加serialVersionUID 私有静态长整型的常量
控制类的版本号 . 当类的版本号修改时,意味着之前的序列化数据全部作废
当反序列化一个类的对象时,如果这个类实现了Serializable接口,那么可以直接还原对象,如果这个类没实现Serializable接口(这个类必然是父类),那么需要调用构造方法来创建对象
对象的克隆
对象的复制:在内存中复制出一个内容完全的相同的对象
Object类: clone() 返回Object 对象复制
-
覆盖clone方法,将访问修饰符提高到public
-
浅拷贝: Object.clone() 需要被克隆的类必须实现Cloneable接口
深拷贝: 对象复制过程中,对象的属性如果又是对象,则递归的进行复制
利用 对象序列化 自定义克隆方法. 可以不实现Cloneable接口
使用 ByteArrayOutputStream 在JVM中将对象写入字节数组, 再用ByteArrayInputStream将对象读回来 public Object clone(){ try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(this); out.close(); byte[] data = bos.toByteArray(); ByteArrayInputStream bis = new ByteArrayInputStream(data); ObjectInputStream in = new ObjectInputStream(bis); Object o = in.readObject(); in.close(); return o; } catch (Exception e) { e.printStackTrace(); return null; } }
字符流
以字符为单位传输数据 处理文本数据
字符的乱码: 当编码方式和解码方式不统一时,可能会有乱码问题(ASCII字符永远没有乱码)
字符的常见编码:
ASCII 编码 英语字符 'A' - 65 'a' - 97 '0' - 48
ISO-8859-1 西欧字符
GB2312 简体中文(有些繁体字和特殊字打不出来)
GBK GB2312的扩展
Big5 繁体中文
Unicode UTF-16 (char) 把一个字符编解为16位,2B UTF-8(变长) 全球统一
字符流
Reader/Writer 字符流的父类 抽象类
FileReader/FileWriter 文件字符流 节点流
BufferedReader/BufferedWriter 缓冲 过滤流
PrintWriter 缓冲
InputStreamReader/OutputStreamWriter 桥转换 将字节流转换为字符流 可以指定编解码方式