You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Oracle字符流示例中int变量存字符占16位是否会浪费2字节?

关于Java IO中read()返回值及CopyCharacters与CopyBytes的区别

首先得澄清一个容易混淆的点:你提到的InputStream.read()返回的int低16位存字符值其实是把字节流和字符流的API搞混啦!实际上,InputStream属于字节流,它的read()方法返回的int值里,只有低8位存储的是读取到的原始字节值(范围0-255),高24位都是0;而字符流(比如FileReader这类Reader子类)的read()方法,返回的int值才是低16位存储Unicode字符值(范围0-65535),高16位为0。

那回到你关心的“会不会浪费2字节”这个问题:其实不用纠结这个——这是Java IO API的设计妥协,用int类型承载读取结果,核心目的是区分“有效数据”和“流结束标记(-1)”。如果直接用byte或char类型,就没办法用-1来标识流结束了(byte的范围是-128到127,char是0到65535)。这种“高位闲置”在现代JVM和硬件环境下的性能影响几乎可以忽略不计,完全是为了API的正确性和一致性必须做的设计。

接下来聊聊CopyCharacters和CopyBytes的核心差异:

  • 流的类型与处理逻辑不同:

    • CopyCharacters用的是字符流:FileReader和FileWriter会自动根据系统默认编码(也可以手动指定编码)把文件中的字节转换成字符,再把字符转换回字节写入目标文件,本质是按字符为单位处理数据。
    • CopyBytes用的是字节流:FileInputStream和FileOutputStream完全按原始字节读写,不做任何编码转换,适合处理二进制文件或者不需要编码转换的场景。
  • read()返回值的有效位不同:

    • 在CopyCharacters里,int c存储的是字符流读取结果:低16位是Unicode字符值,高16位为0,返回-1时表示流读取完毕。
    • 在CopyBytes里,int c存储的是字节流读取结果:低8位是原始字节值,高24位为0,返回-1表示流结束。

最后附上你提供的CopyCharacters完整代码:

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 7及以上版本,更推荐用try-with-resources语法来管理流资源,它会自动关闭实现了AutoCloseable接口的资源,代码更简洁安全:

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

public class CopyCharacters {
    public static void main(String[] args) throws IOException {
        try (FileReader inputStream = new FileReader("xanadu.txt");
             FileWriter outputStream = new FileWriter("characteroutput.txt")) {
            int c;
            while ((c = inputStream.read()) != -1) {
                outputStream.write(c);
            }
        }
    }
}

内容的提问来源于stack exchange,提问作者Antee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:59:41