用于读写文件的适当Java类?

die*_*lar 10 java file-io serialization file text-files

阅读一些关于Java文件I/O管理的资料,我知道输入和输出操作有多种替代方案.

这些是:

  • BufferedReaderBufferedWriter
  • FileReaderFileWriter
  • FileInputStreamFileOutputStream
  • InputStreamReaderOutputStreamWriter
  • Scanner

这些是文本文件管理的最佳替代方案吗?什么是序列化的最佳替代方案?Java NIO对此有何评论?

Joa*_*uer 20

两种数据

一般来说,有两个"世界":

  • 二进制数据
  • 文本数据

当它是一个文件(或插座,或在DB一个BLOB,或...),那么它总是二进制数据第一次.

一些二进制数据可以被视为文本数据(涉及称为"编码"或"字符编码"的东西).

二进制数据

每当你想处理二进制数据时,你需要使用InputStream/ OutputStreamclasses(通常,包含Stream其名称的所有内容).

这就是为什么有a FileInputStream和a FileOutputStream:那些读取写入文件并处理二进制数据的原因.

文本数据

无论何时想要处理文本数据,都需要使用Reader/ Writerclasses.

无论什么时候你需要将二进制数据转换为文本(反之亦然),那么你需要某种编码(常见的是UTF-8,UTF-16,ISO-8859-1(和相关的)和好的旧美国 - ASCII)."幸运的是"Java平台还有一个称为"默认平台编码"的东西,它会在需要时使用,但代码没有指定.

平台默认编码是一个双面剑,但是:

  • 它使得编写代码更容易,因为你不必为每个操作的编码,但
  • 它可能与您拥有的数据不匹配:如果平台默认编码为ISO-8859-1且您读取的文件实际上是UTF-8,那么您将得到一个混乱的输出!

对于阅读,我们还应该提到BufferedReader哪些可以包围任何其他,Reader并添加一次处理整行的能力.

Scanner是一个特殊的类,用于解析文本输入到标记.它对结构化文本最有用,但经常用于System.in提供从stdin读取数据的非常简单的方法(即用户在键盘上输入的内容).

弥补差距

现在,令人困惑的是,有些类可以在这些世界之间形成桥梁,这些世界通常在其名称中包含两个部分:

  • 一个InputStreamReader 消耗一个InputStream本身就是一个Reader.
  • 一个OutputStreamWriter Writer写入OutputStream.

然后有"快捷类"基本上结合了两个经常组合的类.

  • a FileReader基本上是a FileInputStream和a的组合InputStreamReader
  • a FileWriter基本上是a FileOutputStream和a的组合OutputStreamWriter

请注意,FileReaderFileWriter更复杂的"手工构建"替代方案相比,它们有一个主要缺点:它们总是使用平台默认编码,这可能不是您想要做的!

怎么样序列化?

ObjectOutputStream并且ObjectInputStream是用于序列化的特殊流.

由于类的名称意味着序列化仅涉及二进制数据(即使序列化String对象),因此您将要*Stream专门使用类.只要你避免任何Reader/ Writer类,你应该没事.

更多资源