首页 > 解决方案 > 在 Oracle 网站上对字符流示例代码感到困惑

问题描述

当我从Oracle 网站阅读以下内容时,我了解到 int 变量在其最后 16 位中保存了一个字符值inputStream.read()

那么它总是浪费2个字节吗?

CopyCharacters 与 CopyBytes 非常相似。最重要的区别是 CopyCharacters 使用 FileReader 和 FileWriter 代替 FileInputStream 和 FileOutputStream 进行输入和输出。请注意,CopyBytes 和 CopyCharacters 都使用一个 int 变量来读取和写入。但是,在 CopyCharacters 中,int 变量在其最后 16 位中保存一个字符值;在 CopyBytes 中,int 变量在其最后 8 位中保存一个字节值。

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

public class CopyCharacters {
    public static void main(String[] args) throws IOException {

        FileReader inputStream = null;
        FileWriter outputStream = null;

        try {
            inputStream = new FileReader("xanadu.txt");
            outputStream = new FileWriter("characteroutput.txt");

            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (outputStream != null) {
                outputStream.close();
            }
        }
    }
}

标签: java

解决方案


那么它总是浪费2个字节吗?

嗯……是的。在这种情况下为 2 个字节Reader或在这种情况下为 3 个字节InputStream

这种浪费是必要的,原因如下:

  1. 两者都InputStream.read()需要Reader.read()返回一个值来表示“流的结束”。正如javadocs所说:

    InputStream.read():从输入流中读取数据的下一个字节。值字节作为 int 返回,范围为 0 到 255。如果由于到达流的末尾而没有可用的字节,则返回值 -1。

    Reader.read():将读取的字符返回为 0 到 65535 (0x00-0xffff) 范围内的整数,如果已到达流的末尾,则返回 -1。

    额外的流结束值意味着返回类型read()不能(分别)bytechar。(另见最后一个原因......)

  2. 事实证明,“浪费”的 2 或 3 个字节无关紧要。即使是一个简单的 Java 程序也会使用兆字节的内存。(事实上​​,即使是微不足道的 C 程序也会使用数十或数百 KB 的内存……如果考虑到它们使用的库代码的话。)

  3. 返回 a byteorchar可能无论如何都不会节省内存。在典型的现代系统中,局部变量(偶数bytechar)以字对齐方式存储在堆栈中。这样做是因为使用字对齐地址访问内存通常更快。

  4. 用异常替换-1以另一种方式效率低下。在 Java 中抛出和捕获异常比对-1.


推荐阅读