File 类
java.io.File 类:文件和文件目录路径的抽象表示形式,与平台无关。
File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
Java File 类提供一个常量,表示路径分隔符:separator。
IO 流
Java程序中,对于数据的输入/输出(IO)操作以流(stream)的方式进行。
- 输入 input:读取外部数据(磁盘等)到程序(内存)中。
- 输出 output:将程序(内存)数据输出到磁盘等外部设备中。
流的分类:
- 按操作数据单位不同分为:字节流(8 bit)、字符流(16 bit)。
- 按数据流的流向不同分为:输入流、输出流。
- 按流的角色的不同分为:节点流、处理流。
- 节点流:直接从数据源或目的地读写数据。
- 处理流:不直接连接到数据源或目的地,而是“连接”在已存在的流(节点流或处理流)之上,通过对数据的处理为程序提供更为强大的读写功能。
节点流(文件流)
文件流用于读取和写入文件,Java 提供 FileInputStream、FileOutputStream、FileReader 和 FileWriter 四种文件流。
处理流
缓冲流
为了提高数据读写的速度,Java API 提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组,缺省使用 8192 个字节(8KB)的缓冲区。
缓冲流要套接在相应的节点流之上,根据数据操作单位可以把缓冲流分为:
- BufferedInputStream 和 BufferedOutputStream
- BufferedReader 和 BufferedWriter
当使用BufferedInputStream 读取字节文件时,BufferedInputStream会一次性从文件中读取 8192 个字节,存在缓冲区中。直到缓冲区装满了,才重新从文件中读取下一个 8192 个字节数组。
向流中写入字节时,不会直接写到文件,先写到缓冲区中直到缓冲区写满,BufferedOutputStream 才会把缓冲区中的数据一次性写到文件里。使用方法 flush() 可以强制将缓冲区的内容全部写入输出流。
关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也会相应关闭内层节点流。close 方法不但会关闭流,而且会在关闭流之前刷新缓冲区。
1 | BufferedReader br = null; |
转换流
转换流提供了在字节流和字符流之间的转换,Java API 提供了两个转换流:
InputStreamReader:将 InputStream 转换为 Reader(解码)。
- 构造器:public InputStreamReader(InputStream in)、public InputSreamReader(InputStream in,String charsetName)
OutputStreamWriter:将 Writer 转换为 OutputStream(编码)。
- 构造器:public OutputStreamWriter(OutputStream out)、public OutputSreamWriter(OutputStream out,String charsetName)
字节流中的数据都是字符时,转成字符流操作更高效。
很多时候使用转换流来处理文件乱码问题,实现编码和解码的功能。
对象流
用于存储和读取基本数据类型数据或对象的处理流。它的强大之处就是可以把 Java 中的对象写入到数据源中,也能把对象从数据源中还原回来。
- 序列化:用 ObjectOutputStream 类保存基本类型数据或对象的机制。
- 反序列化:用 ObjectInputStream 类读取基本类型数据或对象的机制。
ObjectOutputStream 和 ObjectInputStream 不能序列化 static 和 transient 修饰的成员变量。
对象序列化
序列化的好处在于可将任何实现了 Serializable 接口的对象转化为字节数据,使其在保存和传输时可被还原。序列化的要求:
- 实现了 Serializable 接口。
- 类内部定义了 serialVersionUID 常量。
凡是实现 Serializable 接口的类都有一个表示序列化版本标识符的静态变量:private static final long serialVersionUID;
如果类没有显示定义这个静态常量,其值是 Java 运行时环境根据类的内部细节自动生成的。若类的实例变量做了修改,serialVersionUID 可能发生变化(建议显式的声明)。
Java 的序列化机制是通过在运行时判断类的 serialVersionUID 来验证版本一致性的。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体类的 serialVersionUID 进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常(InvalidCastException)。
随机读取文件流
RandomAccessFile 声明在 java.io 包下,但直接继承于 java.lang.Object 类。并且它实现了 DataInput、DataOutput 这两个接口,也就意味着这个类既可以读也可以写。
RandomAccessFile 类支持随机访问的方式,程序可以直接跳到文件的任意地方来读、写文件:
- 支持只访问文件的部分内容。
- 可以向已存在的文件后追加内容。
RandomAccessFile 对象包含一个记录指针,用以标示当前读写处的位置。RandomAccessFile 类对象可以自由移动记录指针:
- long getFilePointer():获取文件记录指针的当前位置。
- void seek(long pos):将文件记录指针定位到 pos 位置。
RandomAccessFile 类的构造器:
- **public RandomAccessFile(File file, String mode)**。
- **public RandomAccessFile(String name, String mode)**。
其中,mode 指定文件的访问模式:
- r:只读。
- rw:读取和写入。
- rwd:读取和写入,同步文件内容的更新(立即写入到磁盘中)。
- rws:读取和写入,同步文件内容和元数据的更新。