OutputStreamWriter与FileWriter

时间:2012-07-07 00:07:56

标签: java

我不明白这两个类之间的区别。你什么时候使用一个?我知道FileWriter可以将字符输出到文件,但据我所知,OutputStreamWriter也是如此。这是我测试的一些代码,它们似乎工作相同,我没有添加异常处理的东西,但让我们假设它在那里。

FileWriter writer = new FileWriter("C:\\Users\\owner\\Desktop\\demo.txt");
writer.write("hello");
writer.close();

我也试过这段代码:

File file = new File("C:\\Users\\owner\\Desktop\\demo.txt");
os = new OutputStreamWriter(new FileOutputStream(file));
os.write("hello");
os.close();

这些似乎对我来说都是一样的。奇怪的事情发生的唯一时间是我尝试在write()方法中放入一个int值。对于FileWriter示例,我的demo.txt完全为空。对于OutputStreamWriter示例,我在文本文件中得到了一些奇怪的符号。我正在阅读一本java书籍,我对OutputStreamWriter的唯一解释是它“将一个字符串转换为一个字节流”所以我不应该在第二个例子中看到我的文本文件中的一些字节?

非常感谢一些澄清。

4 个答案:

答案 0 :(得分:36)

XXXInputStream和XXXOutputStream(其中XXX变化,有很多选项)处理8位字节。例如,OutputStream.write(byte[] c);

XXXWriter或XXXReader处理16位字符。例如,Reader.read(char[] cbuf)

OutputStreamWriter将OutputStream转换为Writer。您可能已经猜到,InputStreamReader从InputStream转换为Reader。我不知道任何反向的类,即将Reader转换为InputStream。

FileWriter是一个与文件对话的Writer。由于Java String内部使用字符(16位以便它们可以处理Unicode),因此FileWriter是用于Unicode字符串的自然类。

FileOutputStream是一个用于将字节写入文件的OutputStream。 OutputStreams不接受字符(或字符串)。通过将它包装在OutputStreamWriter中,您现在拥有一个Writer,它接受字符串。

现在,真正的问题是,你什么时候使用读者/写作者和流?我已经使用Java多年了,有时我也会感到困惑。我认为以下是正确的:

便利指南 - 如何决定使用哪种方法:

  1. 如果您正在处理二进制数据(例如图像),请使用Streams。
  2. 如果您使用的是非ASCII Unicode字符,例如中文,用法 读/写器。
  3. 如果您使用普通的ASCII文本(传统的0-127个字符),您可以(通常)使用它们。
  4. 其他一些链接:

    inputstream and reader in Java IO

    InputStream vs InputStreamReader

答案 1 :(得分:14)

本身实际上没有区别,FileWriter只是一个便利类。它会扩展OutputStreamWriter并自行创建所需的FileOutputStream

关于write(int):该方法将具有指定代码点的单个字符写入流,它写入数值的文本表示。

对于空文件,请注意,当您希望将已写入的内容刷新到底层存储(无论是文件或网络流还是您能想到的任何内容)时,应始终刷新缓冲区。写完之后,只需致电os.flush()即可 编辑:正如Thilo正确提到的那样,关闭流应该已经刷新它(以及所有底层流)。

最后但并非最不重要的是,您应该几乎总是明确指定您希望Writer写入的字符集/编码。编写器写入字符,而OutputStreams写入字节,因此您必须指定这些字符应如何编码为字节。如果您未指定编码,则会使用系统默认值,这可能不是您想要的。

答案 2 :(得分:3)

这是here

  

在java.io中,您可以执行字节IO或字符IO。可以使用字节IO   对于任何形式的数据,不对该数据进行任何解释   代表。字符IO意味着信息   表示为字符序列。

     

对于字节IO,我们有各种类型的InputStream / OutputStream类   比如示例中的FileOutputStream 1)。对于角色数据   有各种形式的Reader / Writer类,如FileWriter   你的榜样。在两种情况下都可以进行缓冲,因此可以进行缓冲   BufferedWriter和BufferedOutputStream类。

     

要做角色,IO角色必须在某些时候进行转换   使用某种形式的编码来字节数据。 FileWriter为此做到了   你,这就是为什么它有一个构造函数来进行编码   用文件名。常见的编码包括UTF-8,UTF-16和   US-ASCII。

     

OutputStreamWriter是一个只进行编码的类   字符。这就是为什么它是一个Writer,它的构造函数需要一个   OutputStream作为带有可选编码参数的参数。

     

如果省略了FileWriter和。的显式编码规范   ByteArrayOutputStream将使用您平台的默认编码。   这是非常小心的,因为它会有所不同   不同的JVM。

答案 3 :(得分:2)

如果要更改编码,请使用OutputStreamWriter而不是FileOutputStream。 FileOutputStream是一个用于编写字符文件的方便的类。它使用默认编码。

强制编码为UTF-8,如下所示:

OutputStreamWriter osw = new OutputStreamWriter(
    new FileOutputStream(exportPath),
    Charset.forName("UTF-8").newEncoder() 
);