Java:PrintStream 和 PrintWriter 的区别
Posted
技术标签:
【中文标题】Java:PrintStream 和 PrintWriter 的区别【英文标题】:Java: Difference between PrintStream and PrintWriter 【发布时间】:2011-02-18 19:17:13 【问题描述】:PrintStream
和 PrintWriter
有什么区别?它们有许多共同的方法,因此我经常将这两个类混合在一起。此外,我认为我们可以将它们用于完全相同的事情。但是必须有区别,否则就只有一个类。
我已经搜索了档案,但找不到这个问题。
【问题讨论】:
+1 好问题,我也混淆了这两个类,API doc 也没有多大帮助。 另一个区别是自动刷新的工作方式。对于 writer,输出中存在 \n 字符会触发 flush()。但是在字节流(PrintStream)中只有字节。 autoflush 然后按照 Javadoc 中的描述工作,基于:“平台自己的行分隔符概念,而不是换行符”。 【参考方案1】:这听起来有点轻率,但PrintStream
打印到OutputStream
,PrintWriter
打印到Writer
。好的,我怀疑我会因为陈述显而易见的事情而得到任何积分。但还有更多。
那么,OutputStream
和 Writer
之间有什么区别?
两者都是流,主要区别在于 OutputStream
是字节流,而 Writer
是字符流。
如果OutputStream
处理字节,那么PrintStream.print(String)
呢?它使用默认平台编码将字符转换为字节。使用默认编码通常是一件坏事,因为它会在从一个平台移动到另一个平台时导致错误,尤其是当您在一个平台上生成文件并在另一个平台上使用它时。
使用Writer
,您通常会指定要使用的编码,避免任何平台依赖性。
既然主要目的是写入字符而不是字节,为什么还要在 JDK 中使用 PrintStream
? PrintStream
在引入读写器字符流时早于 JDK 1.1。我想 Sun 会弃用 PrintStream
,如果只是因为它被广泛使用。 (毕竟,您不希望每次对 System.out
的调用都生成已弃用的 API 警告!此外,将标准输出流上的类型从 PrintStream
更改为 PrintWriter
会破坏现有的应用程序。)
【讨论】:
这也是我的想法——但事实并非如此。甚至 PrintStream 在后台也维护了一个 Writer - 如果你传递一个 OutputStream,它会包装它。 @Jon - 内部有一个 Writer,但它写入 OutputStream,因此最终效果是 PrintStream 写入 OutputStream - 发生字符到字节的转换,并使用默认平台编码.在 PrintWriter 中对 char->byte 转换没有这样的要求,你可以一直保持字符。 从 Java 1.5 开始,PrintStream
已经不限于使用平台默认编码;有接受字符集名称的构造函数。因此PrintStream
和PrintWriter
之间的区别在于PrintWriter
不能写入原始字节并且这两个类包装了不同类型的目的地。
值得注意的是,它们的行为也存在显着差异,虽然它们有效地共享接口PrintStream
的print()
方法是调用write()
的便捷函数,因此它们触发如果启用,则自动刷新。另一方面,PrintWriter
在调用 print()
后不会自动刷新。我今天一直在向一些初学者演示 Java,这让一些不熟悉手动刷新的学生感到困惑。否则你的答案很好。
@ieXcept 你说得对,也许我应该澄清一下我指的是默认行为,因为他们使用的是由某个库包装的 printwriter
。【参考方案2】:
从 JDK 1.4 开始,可以为 PrintStream 指定字符编码。因此,PrintStream 和 PrintWriter 之间的区别仅在于自动刷新行为,而 PrintStream 不能包装 Writer。
【讨论】:
【参考方案3】:像 PrintWriter 这样的编写器用于文本输出,流用于二进制输出。作者为您处理字符集。 Streams 不会,因为它假定您不想要这种转换,这会弄乱您的二进制数据,并且如果您这样做了,就会使用编写器。
【讨论】:
PrintStream 除外,因为它采用编码方式,因此它可以处理比标准 OutputStream 更多的内容。 System.out 的唯一目标是打印字符串,但它实际上是一个 PrintStream,这听起来很奇怪。 “编写器为您处理字符集的东西”——只有编写器负责将字符转换为字节。并非所有作家都这样做。【参考方案4】:您可以将原始字节写入 Stream 而不是写入器。 PrintWriter javadoc 列出了其他差异(最重要的是,能够在流上设置编码,以便它可以解释我所说的原始字节)。
【讨论】:
使用 PrintStream 也可以指定编码【参考方案5】:来自 Horstmann 的 core java
Java 老手可能想知道 PrintStream 类和 System.out 发生了什么。在 Java 中 1.0,PrintStream 类通过删除简单地将所有 Unicode 字符截断为 ASCII 字符 最高字节。 (当时,Unicode 仍然是 16 位编码。)显然,这不是一个干净的或 可移植的方法,并且随着 Java 1.1 中读取器和写入器的引入而得到修复。为了 与现有代码的兼容性,System.in、System.out 和 System.err 仍然是输入/输出 流,而不是读者和作家。但是现在 PrintStream 类在内部转换了 Unicode 以与 PrintWriter 相同的方式将字符转换为默认主机编码。类型的对象 当您使用 print 和 println 方法时,PrintStream 的行为与打印编写器完全相同,但不同于 打印编写器,它们允许您使用 write(int) 和 write(byte[]) 方法输出原始字节。
【讨论】:
【参考方案6】:Printwriter 是对打印流的增强。
I.E.用于特定目的的打印流。
【讨论】:
以上是关于Java:PrintStream 和 PrintWriter 的区别的主要内容,如果未能解决你的问题,请参考以下文章
Java IO(十九)PrintStream 和 PrintWriter
Java:PrintStream 和 PrintWriter 的区别