为什么Java OutputStream.write()采用整数但写入字节

时间:2009-09-10 21:39:20

标签: java io outputstream

我正在编写一个OutputStream,只是在OutputStream接口中注意到了这一点,

   public abstract void write(int b) throws IOException;

这个调用会向流写一个字节,但为什么它将整数作为参数?

5 个答案:

答案 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个字节。