第十八章 Java I/O系统
在Java中把不同的输入/输出源抽象表述为"流"
1、分类
1.1、按流向分(这里的输入、输出都是从程序运行所在的内存的角度划分)
输入流:只能从中读取数据,而不能向其写入数据
输出流 :只能向其写入数据,而不能从中读取数据
1.2、按操作单元分
字节流:以字节(8bit)为单位
字符流:以16位字符为单位
1.3、按角色分
节点流:可以从/向一个特定的IO设备(如磁盘、网络)读/写数据的流
处理流:处理流是对一个已存在的流进行连接或封装,通过封装后的流来实现数据读/写功能
2、RandomAccessFile
“随机访问”文件,既可以读取文件内容,也可以向文件输出,可以直接跳转到文件的任意地方读写数据。
public class Test {
public static void main(String[] args) throws Exception {
RandomAccessFile accessFile = new RandomAccessFile("poet.txt", "rw");
byte[] buffer = new byte[1024];
while (accessFile.read(buffer) > 0){
System.out.println(new String(buffer));
}
accessFile.write("欲穷千里目".getBytes());
accessFile.write("更上一层楼".getBytes());
}
}
3、序列化
3.1、Serializable 标记接口
实现Serializable的反序列化无须通过构造器来初始化Java对象
- 所有保存到磁盘的对象都有一个序列化编号
- 当程序试图序列化一个对象时,程序将先检查该对象是否已经被序列化过,只有该对象从未被序列化过(在本次虚拟机中),系统才会将该对象转换成字节序列并输出
- 如果某个对象已经序列化过,程序将只是直接输出一个序列化编号,而不是再次重新序列化该对象
3.2、Externalizable
实现Externalizable的反序列化必须提供public的无参构造函数
需要实现readExternal、writeExternal方法
注意:
- 对象的类名、实例变量(基本类型、数组、引用)都会被序列化;方法、类变量、transient实例变量都不会被序列化
- 实现Serializable接口的类中用transient修饰的实例变量都不会被序列化
- 保证序列化对象的实例变量类型也是可序列化的,否则用transient修饰
- 反序列化对象时必须有该对象的class文件,读取顺序与写入顺序相同
4、NIO
4.1、Buffer
A buffer is a linear, finite sequence of elements of a specific primitive type. Aside from its content, the essential properties of a buffer are its capacity, limit, and position.
抽象类,缓存数据的容器,常用子类:ByteBuffer、CharBuffer等,静态方法XxxBuffer allocate(int capacity) 创建对应的实例对象,Buffer中的几个重要概念:
capacity:缓冲区容量
limit:可读写界限
position:下一个可读写位置索引
mark:已读写区域中的标记
0<=mark<=position<=limit<=capacity
Buffer中的几个重要方法:
flip():设置 limit=position,position=0,可以从buffer读取数据
clear():设置position=0,limit=capacity,可以向buffer写入数据
4.2、Channel
A channel represents an open connection to an entity such as a hardware device, a file, a network socket, or a program component that is capable of performing one or more distinct I/O operations, for example reading or writing.
接口,类似流对象,常用的实现类:FileChannel、DatagramChannel、SocketChannel、ServerSocketChannel等,Channel中的几个重要方法:
read():Reads a sequence of bytes from this channel
write() :Writes a sequence of bytes to this channel
map():Maps a region of this channel's file directly into memory
public class Test{
public static void main(String[] args) throws Exception{
FileInputStream in = new FileInputStream("poet.txt");
FileChannel fc = in.getChannel();
ByteBuffer bf = ByteBuffer.allocate(1024);
while (fc.read(bf)!=-1){
bf.flip();
Charset cs = Charset.forName("UTF-8");
// 解码器
CharsetDecoder cd = cs.newDecoder();
CharBuffer cb = cd.decode(bf);
System.out.println(cb);
bf.clear();
}
fc.close();
in.close();
}
}
File、Path访问文件系统接口
Files、Paths文件系统工具类
不要忘记关闭IO资源!!!