为什么 Java OutputStream.write() 取整数但写字节
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1407893/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why Java OutputStream.write() Takes Integer but Writes Bytes
提问by ZZ Coder
I am writing an OutputStream, just noticed this in the OutputStream interface,
我正在写一个OutputStream,刚刚在OutputStream接口中注意到了这一点,
public abstract void write(int b) throws IOException;
This call write one byte to the stream but why it takes integer as an argument?
此调用将一个字节写入流,但为什么它将整数作为参数?
采纳答案by Bill K
Actually I've been working with bytes a bit lately and they can be annoying. They up-convert to ints at the slightest provocation and there is no designation to turn a number into a byte--for instance, 8l will give you a long value 8, but for byte you have to say (byte)8
实际上,我最近一直在使用字节,它们可能很烦人。它们在最轻微的挑衅下向上转换为整数,并且没有将数字转换为字节的指定——例如,8l 会给你一个长值 8,但对于字节你必须说 (byte)8
On top of that, they will (pretty much) always be stored internally as ints unless you are using an array (and maybe even then.. not sure).
最重要的是,除非您使用数组(甚至可能……不确定),否则它们将(几乎)始终在内部存储为整数。
I think they just pretty much assume that the only reason to use a byte is i/o where you actually need 8 bits, but internally they expect you to always use ints.
我认为他们只是假设使用字节的唯一原因是实际上需要 8 位的 i/o,但在内部,他们希望您始终使用整数。
By the way, a byte can perform worse since it always has to be masked...
顺便说一句,一个字节的性能可能更差,因为它总是必须被屏蔽......
At least I remember reading that years ago, could have changed by now.
至少我记得几年前读过,现在可能已经改变了。
As an example answer for your specific question, if a function (f) took a byte, and you had two bytes (b1 and b2), then:
作为您特定问题的示例答案,如果函数 (f) 占用一个字节,而您有两个字节(b1 和 b2),则:
f(b1 & b2)
wouldn't work, because b1 & b2 would be up-converted to an int, and the int couldn't be down-converted automatically (loss of precision). So you would have to code:
行不通,因为 b1 和 b2 会向上转换为 int,并且 int 不能自动向下转换(精度损失)。所以你必须编码:
f( (byte)(b1 & b2) )
Which would get irritating.
这会让人恼火。
And don't bother asking WHY b1 & b2 up-converts--I've been cussing at that a bit lately myself!
并且不要打扰问为什么 b1 和 b2 向上转换——我自己最近一直在诅咒这个!
回答by sfish
So you can signal EOF:
所以你可以发出EOF信号:
"Notice that read() returns an int value. If the input is a stream of bytes, why doesn't read() return a byte value? Using a int as a return type allows read() to use -1 to indicate that it has reached the end of the stream."
“注意 read() 返回一个 int 值。如果输入是一个字节流,为什么 read() 不返回一个字节值?使用 int 作为返回类型允许 read() 使用 -1 来表示它已经到了溪流的尽头。”
http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html
http://java.sun.com/docs/books/tutorial/essential/io/bytestreams.html
回答by Atmocreations
according to javadoc for OutputStream, the 24 high-order bits are ignored by this function. i think the method exists for compatibility reasons: therefore you don't need to convert to byte first and you can simply pass an integer.
根据OutputStream 的javadoc,此函数忽略 24 个高位。我认为该方法的存在是出于兼容性原因:因此您无需先转换为字节,您只需传递一个整数即可。
regards
问候
回答by Gary
The Java IOStream classes have been a part of Java since 1.0. These classes only deal with 8 bit data. My guess is that the interface was designed like this so that the one write(int b) method would be called for int, short, byte, and char values. These are all promoted to an int. In fact since most JVMs run on 32 bit machines, the int primitive is the most efficient type to deal with. The compiler is free to store types such as bytes using 32 bits anyway. Interestingly, byte[] really is stored as a sequence of 8 bit bytes. This makes sense since an array could be quite large. However in the case of single primitive values such as int or byte, the ultimate space occupied at runtime doesn't really matter as long as the behavior is consistent with the spec.
Java IOStream 类从 1.0 开始就成为 Java 的一部分。这些类只处理 8 位数据。我的猜测是接口是这样设计的,以便为 int、short、byte 和 char 值调用一个 write(int b) 方法。这些都被提升为一个整数。事实上,由于大多数 JVM 运行在 32 位机器上,因此 int 原语是最有效的类型。无论如何,编译器可以自由地使用 32 位存储类型,例如字节。有趣的是,byte[] 确实存储为 8 位字节的序列。这是有道理的,因为数组可能非常大。然而,在单个原始值(例如 int 或 byte)的情况下,只要行为与规范一致,运行时占用的最终空间并不重要。
More background:
更多背景:
http://www.java-samples.com/showtutorial.php?tutorialid=260
http://www.java-samples.com/showtutorial.php?tutorialid=260
The assumption for the IOStream classes is that the caller only really cares about lowest 8 bits of data even when passing in an int. This is fine as long the caller knows it is really dealing with bytes, but it becomes a problem when underlying data is really text that uses some other character encoding such as multi-byte Unicode. This is why the Reader classes were introduced way back with Java 1.1. If you care about text data and performance, the IOStream classes are faster, but the Reader classes are more portable.
IOStream 类的假设是调用者只真正关心数据的最低 8 位,即使在传入 int 时也是如此。只要调用者知道它确实在处理字节就可以了,但是当底层数据实际上是使用其他字符编码(例如多字节 Unicode)的文本时,这就会成为问题。这就是为什么在 Java 1.1 中引入 Reader 类的原因。如果您关心文本数据和性能,IOStream 类会更快,但 Reader 类更具有可移植性。
回答by Denis Tulskiy
Maybe it's because bytes are signed by default, and files store bytes as unsigned values. That is why read()returns an int - to give 255 instead of -1 for $FF. Same with write(int), you can not store $FF as 255 in a byte.
可能是因为默认情况下字节是有符号的,而文件将字节存储为无符号值。这就是为什么read()返回 int - 为 $FF 提供 255 而不是 -1 的原因。与 相同write(int),您不能在一个字节中将 $FF 存储为 255。

