理解 Java I/O 主要概念
介绍 Java I/O API
"Java I/O" 中的 I/O 代表输入/输出。Java I/O API 提供了应用程序访问外部信息所需的所有工具。对于您的应用程序,“外部”意味着两个元素:您的磁盘,或者更一般地说,您的文件系统(文件系统并不总是模拟磁盘,例如,它们可能驻留在内存中),以及您的网络。事实证明,您可以使用 Java I/O 及其扩展访问第三个元素:非堆内存。
使用 Java I/O API,您可以读取和写入文件,以及使用不同的协议通过网络获取和发送数据。使您能够访问数据库的 API(Java 数据库连接 API)使用 Java I/O API 通过 TCP/IP 访问数据库。许多知名 API 都构建在 Java I/O API 之上。
理解 Java I/O、Java NIO 和 Java NIO2
Java I/O API 是在 90 年代中期与 JDK 的第一个版本一起创建的。
2002 年,随着 Java SE 1.4 的发布,Java NIO 也随之发布,其中包含新的类、概念和功能。NIO 代表非阻塞输入/输出,它概括了此扩展带来的主要功能。Java NIO 的发布并没有真正改变应用程序使用 Java I/O 的方式。您可能觉得需要重写一些 I/O 代码以利用 Java NIO 带来的改进,但 Java I/O 模式保持不变。
2011 年,随着 Java SE 7 的发布,Java NIO2 也随之发布,其中包含更多类和概念。它还带来了 Java I/O 的新模式。Java NIO2 的一些类已在 Java SE 8 中更新,为 Java I/O 带来了更多模式。
本 Java I/O 教程涵盖了 API 的三个部分:Java I/O、Java NIO 和 Java NIO2。
访问文件
Java I/O 中有两个主要概念:定位您需要访问的资源(它可以是文件或网络资源),以及打开到该资源的流。在以下部分,您将看到如何从文件系统访问文件,以及 Java I/O API 在流方面是如何组织的。
在 Java I/O API 中,有两种方法可以访问文件:第一种方法使用 File
类,第二种方法使用 Path
接口。
File
类是在 Java SE 1.0 中引入的:它代表访问文件的传统方式。您可以将此类视为对表示默认文件系统上路径的字符字符串的包装器。路径可以是绝对路径或相对路径,它可以表示普通文件或目录。您可以检查此文件是否存在,是否可以读取或修改它。您还可以对该文件执行操作:创建它、复制它或检查其内容。
从 Java SE 7 开始,Path
接口作为 Java NIO2 API 的一部分被引入。该接口的作用是修复 File
类存在的几个缺陷。
File
类的许多方法在失败时不会抛出异常,这使得无法获得有用的错误消息。例如,如果您调用file.delete()
并且删除操作失败,您的程序将获得一个false
值。但是您无法知道这是因为文件不存在、用户没有权限,还是存在其他问题。- 重命名方法在不同平台上的工作方式不一致。
- 对符号链接没有真正的支持。
- 需要更多对元数据的支持,例如文件权限、文件所有者和其他安全属性。
- 访问文件元数据效率低下。
File
的许多方法无法扩展。在服务器上请求大型目录列表会导致挂起。大型目录还会导致内存资源问题,从而导致拒绝服务。- 无法编写可靠的代码,该代码可以递归遍历文件树并在存在循环符号链接时做出适当的响应。
Path
接口修复了所有这些问题。因此,不再建议使用 File
类。
本教程 有一节 介绍了如何将旧式 File
代码重构为使用 Path
接口。
理解 I/O 流
I/O 流表示输入源或输出目标。流可以表示许多不同类型的源和目标,包括磁盘文件、设备、其他程序和内存数组。
流支持许多不同类型的数据,包括简单字节、基本数据类型、本地化字符和对象。一些流只是传递数据;另一些则以有用的方式操作和转换数据。
无论它们在内部如何工作,所有流都向使用它们的程序呈现相同的简单模型:流是一系列数据。程序使用输入流从源读取数据,一次读取一个项目,并使用输出流将数据写入目标,一次写入一个项目。
数据源和数据目标可以是任何保存、生成或使用数据的对象。显然,这包括磁盘文件,但源或目标也可以是另一个程序、外围设备、网络套接字或数组。
I/O 流与 Java SE 8 中引入的 Stream API 中的流是不同的概念。即使名称相同,这可能会导致混淆,但概念是不同的。
Java I/O API 为资源定义了两种内容
- 字符内容,例如文本文件、XML 或 JSON 文档,
- 以及字节内容,例如图像或视频。
它还定义了对此内容的两种操作:读取和写入。
因此,Java I/O API 定义了四个基本类,它们是抽象的,每个类都模拟一种类型的 I/O 流和一个特定的操作。
读取 | 写入 | |
---|---|---|
字符流 | Reader |
Writer |
字节流 | InputStream |
OutputStream |
所有字节流都继承自 InputStream
和 OutputStream
,其中有很多。本教程中涵盖了其中的一些。
上次更新: 2023 年 1 月 25 日
返回教程列表