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
相关产品推荐
相关产品推荐

