Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中:为什么有些流方法使用int而不是byte甚至char?_Java_Character Encoding_Streaming_Iostream - Fatal编程技术网

在Java中:为什么有些流方法使用int而不是byte甚至char?

在Java中:为什么有些流方法使用int而不是byte甚至char?,java,character-encoding,streaming,iostream,Java,Character Encoding,Streaming,Iostream,为什么一些将byte/char写入流的方法采用int而不是byte/char 有人告诉我,如果是int而不是char: 因为java中的char只有2个字节的长度,这对于已经使用的大多数字符符号来说是可以的,但是对于某些字符符号(中文或其他什么),字符的表示长度超过2个字节,因此我们使用int 这个解释离事实有多远 编辑: 我使用流字来表示二进制和字符流(不仅仅是二进制流) 谢谢。最大可能的代码点为0x10FFFF是正确的,它不适合字符。然而,流方法是面向字节的,而writer方法是16位的。写

为什么一些将
byte/char
写入流的方法采用
int
而不是
byte/char

有人告诉我,如果是
in
t而不是
char
: 因为java中的
char
只有2个字节的长度,这对于已经使用的大多数字符符号来说是可以的,但是对于某些字符符号(中文或其他什么),字符的表示长度超过2个字节,因此我们使用int

这个解释离事实有多远

编辑: 我使用
字来表示二进制和字符流(不仅仅是二进制流)


谢谢。

最大可能的代码点为0x10FFFF是正确的,它不适合字符。然而,流方法是面向字节的,而writer方法是16位的。写一个字节,只看低阶16位。

我不确定你指的是什么,但也许你在想什么?它返回一个整数而不是一个字节,因为返回值被重载,以表示流的结尾(表示为-1)。由于有257个不同的可能返回值,一个字节是不够的


否则,也许您可以提供一些更具体的示例。

在Java中,流是指原始字节。要编写字符,请将流包装到编写器中


虽然写入程序确实有(写入16个低位;由于字节太小,所以是int,由于带符号,所以是short),但您应该使用or。

可能与返回int的read()方法对称。没什么大不了的。

有一些可能的解释

首先,正如一些人所指出的,这可能是因为
read()
必然返回一个int,因此让write()接受int以避免强制转换被认为是优雅的:

int read = in.read();
if ( read != -1 )
   out.write(read);
//vs
   out.write((byte)read);
第二,避免其他铸造案例可能很好:

//write a char (big-endian)
char c;
out.write(c >> 8);
out.write(c);

//vs
out.write( (byte)(c >> 8) );
out.write( (byte)c );
有人告诉我用int代替char:因为java中char的长度只有2个字节,这对于大多数已经使用的字符符号来说是可以的,但是对于某些字符符号(中文或其他什么),字符的表示形式超过了2个字节,因此我们用int代替

假设此时您正在专门讨论
Reader.read()
方法,那么您所叙述的“某人”的陈述实际上是不正确的

确实,某些Unicode代码点的值大于65535,因此不能表示为单个Java
char
。但是,
Reader
API实际上生成了一个Java
char
值序列(或-1),而不是一个Unicode码点序列。这一点在报告中已明确说明

如果您的输入包含一个大于65535的(经过适当编码的)Unicode代码点,那么您实际上需要调用
read()
方法两次才能看到它。您将得到一个UTF-16代理对;i、 e.两个Java
char
值一起表示代码点。事实上,这符合Java字符串、StringBuilder和StringBuffer类的工作方式;它们都使用基于UTF-16的表示法。。。使用嵌入的代理项对

Reader.read()。同样的逻辑解释了为什么
InputStream.read()
返回的是
int
而不是
byte

假设,我假设Java设计人员可以指定
read()
方法抛出异常来通知“流结束”条件。然而,这只会将一个潜在的bug源(未能测试结果)替换为另一个(未能处理异常)。此外,异常的代价相对较高,并且流结束并不是真正的意外/异常事件。简言之,国际海事组织认为,目前的做法更好

(关于
读取器
API的16位特性的另一个线索是
读取(char[],…)
方法的签名。如果不使用代理项对,这将如何处理大于65535的代码点?)

编辑

DataOutputStream.writeChar(int)
的情况似乎有点奇怪。但是,javadoc清楚地指出,参数是以2字节的值编写的。事实上,该实现显然只将底部的两个字节写入底层流

我不认为这是一个很好的理由。无论如何,此()有一个bug数据库条目,标记为“11已关闭,不是缺陷”,并带有以下注释:

“这不是一个好的设计或借口,但它太过成熟,我们无法改变。”

。。。这是一种承认,它是一个缺陷,至少从设计的角度来看


但这不值得大惊小怪,我想。

你应该具体点。特别是,流通常没有与
char
相关的方法,因为它们用于二进制数据;文本数据需要流本身不应该知道的适当编码。普通流只接受二进制数据,即字节,而不是字符或整数。如果你想发送文本,我建议你使用一个具有选定编码的Writer,对于char、short、int等,你可以使用像DataOutputStream这样的adpater。谢谢,但我不是在问如何将字符串写入文件!“使用流字来表示二进制和字符流(不仅仅是二进制流)”,那么你用错了。你应该学会使用正确的语义学,其他任何东西都是浪费的。流仅用于字节,其他接口(Writer/Reader)处理字符和其他更高级别的抽象。