当我从Oracle website中读取以下内容时,我发现int变量在inputStream.read()
的后16位中保存了一个字符值。
那么它总是浪费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();
}
}
}
}
答案 0 :(得分:2)
那么它总是浪费2个字节吗?
嗯...是的。在Reader
情况下为2个字节,在InputStream
情况下为3个字节。
由于以下原因,这种浪费是必要的:
InputStream.read()
和Reader.read()
都需要返回一个代表“流结束”的值。正如javadocs所说:
InputStream.read()
:从输入流中读取下一个数据字节。值字节以int形式返回,范围为0到255。如果由于到达流的末尾而没有字节可用,则返回值-1。
Reader.read()
:以0到65535(0x00-0xffff)范围内的整数返回读取的字符,如果已到达流的末尾,则返回-1。
额外的流结束值意味着read()
的返回类型不能(分别)为byte
或char
。 (另请参阅最后一个原因...)
事实证明,“浪费”的2或3个字节无关紧要。即使是琐碎的Java程序也要使用兆字节的内存。 (实际上,即使是琐碎的C程序也要使用数十或数百千字节的内存...如果您考虑它们使用的库代码。)
返回byte
或char
可能仍然无法节省内存。在典型的现代系统中,局部变量(甚至byte
和char
)都以字对齐方式存储在堆栈上。这样做是因为用字对齐地址访问内存通常更快。
用另一种方法替换-1
会导致效率低下。在Java中引发和捕获异常比对-1
进行简单测试要昂贵得多。