我在 Sun 的命令行 I/O 上查看了本教程。它指出:
您可能期望标准流是字符流,但由于历史原因,它们是字节流。System.out 和 System.err 被定义为 PrintStream 对象。虽然它在技术上是字节流,但 PrintStream 使用内部字符流对象来模拟字符流的许多特性。
有谁知道“历史原因”是什么?
“历史原因”是 Java 1.0 中不存在字符流。显然 Sun 意识到字符翻译模型的不足,在 Java 1.1 中添加了面向字符的 Reader/Writer 类层次结构。
但是对于 System.out 和朋友们来说已经太晚了。
我猜原因是为了向后兼容 POSIX C/C++ 标准 I/O,其中标准输入、标准输出和标准错误(分别相当于 System.in、System.out 和 System.err 的 C/C++ ) 是字节流。在 Windows 中,这些流执行 CRLF 转换,但在 POSIX 系统中,不会发生此类转换,您可以自由读写非字符二进制数据。许多 Unix 实用程序都这样做,例如 GNUgzip
和tar
.
请记住,Java 中的字符使用 16 位 Unicode 字符。最初的 System.in 等需要与支持 Java 的环境兼容,后者(当时在黎明时分)通常不支持 Unicode。这与对行尾的令人讨厌的不同处理一起,意味着字节流是唯一具有相同语义的类型,无论是什么平台。