我正在编写一个OutputStream,只是在OutputStream接口中注意到了这一点,
public abstract void write(int b) throws IOException;
这个调用会向流写一个字节,但为什么它将整数作为参数?
答案 0 :(得分:26)
所以你可以发出EOF信号:
“请注意,read()返回一个int值。如果输入是一个字节流,为什么read()不返回一个字节值?使用int作为返回类型允许read()使用-1表示它已到达流的末尾。“
http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html
答案 1 :(得分:10)
实际上我最近一直在处理字节,它们可能很烦人。它们在最轻微的挑衅时向上转换为整数,并且没有指定将数字转换为字节 - 例如,8l将为您提供长值8,但对于字节,您必须说(字节)8
除此之外,它们(几乎)将始终以内部存储为整数,除非您使用的是数组(甚至可能......但不确定)。
我认为他们只是假设使用字节的唯一原因是实际需要8位的i / o,但在内部他们希望你总是使用整数。
顺便说一下,一个字节的性能会更差,因为它总是需要被屏蔽......
至少我记得多年前的阅读,现在可能已经改变了。
作为您特定问题的示例答案,如果函数(f)占用一个字节,并且您有两个字节(b1和b2),那么:
f(b1 & b2)
无效,因为b1& b2将被上转换为int,并且int无法自动下转换(精度损失)。所以你必须编码:
f( (byte)(b1 & b2) )
这会让人恼火。
不要问为什么b1& b2 up-convert - 我最近一直在讨论这个问题!
答案 2 :(得分:7)
根据OutputStream的javadoc,此函数忽略了24个高位。我认为该方法存在兼容性原因:因此您不需要先转换为字节,只需传递一个整数。
问候
答案 3 :(得分:3)
Java IOStream类自1.0起就成为Java的一部分。这些类只处理8位数据。我的猜测是接口的设计是这样的,这样就可以为int,short,byte和char值调用一个write(int b)方法。这些都被提升为int。事实上,由于大多数JVM在32位机器上运行,因此int原语是最有效的类型。无论如何,编译器可以使用32位自由存储诸如字节之类的类型。有趣的是,byte []确实存储为8位字节的序列。这是有道理的,因为数组可能非常大。但是,对于单个原始值(如int或byte),只要行为与规范一致,运行时占用的最终空间就不重要了。
更多背景资料:
http://www.java-samples.com/showtutorial.php?tutorialid=260
IOStream类的假设是,即使传入int,调用者也只关心最低8位的数据。只要调用者知道它实际上处理的是字节,这就很好了,但当底层数据实际上是使用其他字符编码(如多字节Unicode)的文本时,它就成了问题。这就是使用Java 1.1引入Reader类的原因。如果您关心文本数据和性能,IOStream类更快,但Reader类更易于移植。
答案 4 :(得分:2)
可能是因为字节是默认签名的,而文件将字节存储为无符号值。这就是read()
返回一个int的原因 - 为$ FF提供255而不是-1。与write(int)
相同,您不能将$ FF存储为255个字节。