Java之IO流

IO流相关API总结

Posted by 袁平 on September 25, 2018

前言

本文将讲解Java中一个比较重要的模块–I/O

以下内容是对Java核心技术卷II的总结, 权做个人笔记~


正文


一. 概述

Java I/O流指的是java.io包和java.nio包提供的各种操作文件和输入输出等的API, 具体可以分为两大类: 一类是面向字节的, 一类是面向字符的; 面向字节的API是以InputStreamOutputStream类为基类, 每次以一个字节为单位进行读写操作; 面向字符的API指的是以ReaderWriter为基类, 每次以两个字节为单位进行读写操作, 面向字符的API主要是针对文本操作设计的

可以参见下图:

面向字节:

面向字节

面向字符:

面向字符

: 图片来源


二. 重要概念

2.1 流嵌套

即将不同功能的流嵌套起来, 过滤; 比如: Java中流默认是不被缓冲区缓存的, 也就是说每个read()的调用都会请求操作系统再分发一个字节, 相比之下, 请求一个数据块并将其置于缓冲区中会显得更加高效, 如果我们想使用缓冲机制, 以及用于文件输入方法, 可以使用 BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream("file"));

2.2 Glob模式匹配

即使用正则筛选文件, 如筛选文件后缀名为java的文件: DirectoryStream<Path> entries = Files.newDirectoryStream(Paths.get("/"), "*.java");

Glob模式见下表:

模式 描述 示例
* 匹配路径组成部分中0个或多个字符 *.java匹配当前目录中的所有Java文件
** 匹配跨目录边界的0个或多个字符 **.java匹配在所有子目录中的Java文件
? 匹配一个字符 ????.java匹配所有四个字符的Java文件
[…] 匹配一个字符集合 Test[0-9A-F].java匹配Testx.java, 其中x是一个十六进制数字
{…} 匹配由逗号隔开的多个可选项之一 *.{java, class}匹配所有的Java文件和类class文件
\ 转移上述任意模式中的字符 *匹配所有文件名中包含*的文件

2.3 常用工具类

  1. Files: 使得读写文件和操作文件及文件夹变得简单; 旧的File类中有一个方法可以用来获取一个目录下的所有文件构成的数组, 但是当目录中包含大量文件时, 这个方法的性能非常低, Files类设计了一个方法可以产生Iterable对象, 如下示例代码:
DirectoryStream<Path> entries = Files.newDirectoryStream(Paths.get("/"));
Iterator<Path> iterator = entries.iterator();
for (Path path : entries) {
    System.out.println(path);
}
  1. Paths: Paths可以用来构造Path对象: Paths.get(args), 可以接收一个或多个字符串, 并将它们用默认文件系统分隔符连接起来

2.4 内存映射文件

大多数操作系统都可以利用虚拟内存实现来将一个文件或者文件的一部分”映射”到内存中, 然后这个文件就可以当做是内存数组一样的访问, 中比传统的文件操作要快得多; 如: FileChannel

2.5 易忘类

  1. InputStreamReader, OutputStreamWriter: 可以指定编码

  2. PrintWriter: 以文本格式写出数据

  3. RandomAccessFile: 在任何位置查找或写入数据; 可以用于实现断点续传

  4. DataInputStream: 读取数字

  5. ObjectInputStream, ObjectOutputStream: 读取对象

2.6 文件操作处理效率

方法 时间
普通输入流 110s
带缓冲的输入流 9.9s
随机方访问文件 162s
内存映射文件 7.2s