为什么Java I / O中的字节可以表示字符?
我看到这些字符只是ASCII。然后它不是动态的,对吗?
对此有任何解释吗?
字节流和字符流有什么区别?
答案 0 :(得分:31)
字节不是字符。单独,他们甚至不能代表字符。
计算方面,“字符”是数字代码(或代码序列)与编码或字符集的配对,用于定义代码如何映射到实际-world字符(或空格或控制代码)。
只有与编码配对后,字节才能表示字符。对于某些编码(如ASCII或ISO-8859-1),一个字节可以表示一个字符...并且许多编码甚至是ASCII兼容的(这意味着0到127的字符代码与ASCII的定义对齐)。 。但如果没有原始地图,你就不知道你拥有什么。
没有编码,字节只是8位整数。
您可以通过强制对它们进行编码来以任何方式解释它们。这正是您将byte
转换为char
,比如说new String(myBytes)
等时所做的,甚至是在文本编辑器中编辑包含字节的文件。 (在这种情况下,它是应用编码的编辑器。)这样做,你甚至可能得到一些有意义的东西。但是在不知道原始编码的情况下,您无法确切知道这些字节的意图。
它甚至可能不是文字。
例如,考虑字节序列0x48 0x65 0x6c 0x6c 0x6f 0x2e
。它可以解释为:
Hello.
和兼容的8位编码; dinner
我用了一些8位编码来证明这一点; 䡥汬漮
in big-endian UTF-16 * ; load r101, [0x6c6c6f2e]
; 或其他任何一件事。仅这六个字节无法告诉您哪种解释是正确的。
至少有文字,这就是编码的目的。
但是如果你想要解释是正确的,你需要使用相同的编码来解码那些用于生成它们的字节。这就是了解文本编码方式如此重要的原因。
字节流和字符流之间的区别在于字符流尝试使用字符而不是字节。 (它实际上适用于UTF-16代码单元。但是因为我们知道编码,这对于大多数用途来说已经足够了。)如果它包裹在字节流中,则字符流使用编码来转换从基础字节流读取的字节到char
s(或写入流到字节的char
)。
*注意:我不知道“䡥汬漮”是亵渎甚至没有任何意义......但除非你把它编程为中文,否则计算机也不会。
答案 1 :(得分:9)
字节可以表示一些字符,原因与int可以表示long相同。
Char是16位。字节是8位。此外,char是无符号的,字节是有符号的。
尝试这样做:
char c = 'a';
System.out.println(c);
byte b = (byte)c;
c = (char)b;
System.out.println(c);
这将输出:
a
a
现在尝试用nDash替换'a'(unicode 2013)。像这样:
char c = '–';
System.out.println(c);
byte b = (byte)c;
c = (char)b;
System.out.println(c);
这将输出:
–
答案 2 :(得分:3)
在C和C ++中,char
包含单个字节,类型char
用于表示8位整数,以及单个文本字符。 Java就像那样不。
在Java中,char
和byte
是不同的数据类型。 char
包含单个Unicode字符,该字符(通常)大于一个字节。 byte
保存8位整数。将char
(或char[]
或String
)转换为字节数组(类型byte[]
)时,字符串会根据某些字符编码进行编码(通常为UTF- 8),结果是如果特定字符串是根据该字符编码写入的,将如何存储在内存(或磁盘)上。
Java IO支持直接从磁盘读取字节数组(byte[]
),因为这通常适用于二进制文件(即非文本文件,其中不应转换换行符,并且字符串不应该'重新编码)。该文件中的字节可能对应于8位编码中的字符(如ASCII或ISO8859- *),但如果您要以这种方式使用它们,则应该进行显式转换char[]
或String
)。
答案 3 :(得分:0)
它是一个字节的原因是由于历史上的美国计算。当基本计算概念被发明时,内存,速度,存储都非常昂贵(并且大)。设计非常简化,因此专注于北美英语世界(在某种程度上,仍然是)。
多个字节,如int,仅在外国(到美国)市场开放并且计算机具有更多RAM和存储空间之后才添加。世界使用复杂的书写系统,例如中文,每个字符需要多个字节。您可能来自世界上需要多字节字符的部分。当我在北美学习编程时,我甚至需要考虑ASCII字节字节。 Java设计师大多来自北美。
例如,根据我的北美abcdefghijklmnopqrstuvwxyz
标准,中文logographical书写字母巨大。