阅读一些有关Java文件I/O管理的资料,我知道了有不止一种输入和输出操作的选择。
它们分别是:
BufferedReader
和BufferedWriter
FileReader
和FileWriter
FileInputStream
和FileOutputStream
InputStreamReader
和OutputStreamWriter
Scanner
类
这些中哪一个是文本文件管理的最佳选择?序列化的最佳选择是什么?Java NIO 对此有何说法?
阅读一些有关Java文件I/O管理的资料,我知道了有不止一种输入和输出操作的选择。
它们分别是:
BufferedReader
和 BufferedWriter
FileReader
和 FileWriter
FileInputStream
和 FileOutputStream
InputStreamReader
和 OutputStreamWriter
Scanner
类这些中哪一个是文本文件管理的最佳选择?序列化的最佳选择是什么?Java NIO 对此有何说法?
一般来说有两个“世界”:
当它是一个文件(或套接字,或数据库中的BLOB等),那么它始终是二进制数据。
其中一些二进制数据可以被视为文本数据(这涉及到称为"编码"或"字符编码"的东西)。
每当您想处理二进制数据时,您需要使用InputStream
/OutputStream
类(通常,名称中包含Stream
的所有内容)。
FileInputStream
和 FileOutputStream
:它们可以读取和写入文件,并处理二进制数据。
每当你需要处理 文本 数据时,你就需要使用 Reader
/Writer
类。
每当你需要将二进制数据转换为文本(或者反之亦然),那么你就需要一些编码方式(常见的有 UTF-8、UTF-16、ISO-8859-1(及其相关编码方式)以及老式的 US-ASCII)。"幸运的是",Java 平台还有一种叫做 "默认平台编码" 的东西,当代码没有指定编码方式时,Java 就会使用它。
然而,默认平台编码方式也是一个双刃剑:
对于阅读,我们还应该提到BufferedReader
,它可以包装在任何其他Reader
周围,并添加处理整行的能力。
Scanner
是一种特殊的类,旨在将文本输入解析为标记。它最适用于结构化文本,但通常用于System.in
,以提供从stdin(即用户在键盘上输入的内容)读取数据的非常简单的方法。
现在,令人困惑的是,有些类可以在这些世界之间架起桥梁,它们的名称通常包含两部分:
InputStreamReader
是一个消耗 InputStream
的读取器,本身是一个 Reader
。OutputStreamWriter
是一个 Writer
,用于向 OutputStream
写入数据。还有一些"快捷类",它们基本上结合了经常结合的两个其他类。
FileReader
基本上是一个 FileInputStream
和 InputStreamReader
的组合。FileWriter
基本上是一个 FileOutputStream
和 OutputStreamWriter
的组合。请注意,与更复杂的“手工构建”的选择相比,FileReader
和FileWriter
存在一个主要缺点:它们始终使用平台默认编码,这可能不是您想要的!
ObjectOutputStream
和ObjectInputStream
是用于序列化的特殊流。
正如类名所示,序列化仅涉及二进制数据(即使是序列化String
对象),因此您应该专门使用*Stream
类。只要避免任何Reader
/Writer
类,您就应该没问题。
nio
简单地意味着 "新 I/O":https://en.wikipedia.org/wiki/New_I/O - Mark Whitaker