理解问题 Java InputStream 读取方法

Problems understanding Java InputStream read method

假设我有一个输入流。如果我错了请纠正我,但 InputStream 中的所有数据都保存为字节,例如以下文本: "Why not with ♥?" 现在我想知道,这个文本是如何转换为字节数组的,因为我不知道(例如)那个 ♥ 是如何保存的。 如果我打电话给

InputStream myInputStream = os.getInputStream();
byte[] b = new byte[1];
while ((in.read(b)) != -1) {
            System.out.write(b, 0, 1);
}

然后我的 byteArray(长度为 1)将在每个循环中填充下一个字节。

int.read(b)

returns 一个整数值,稍后将转换为字符。 所以,如果我看一下 Java 文档,您会发现类似这样的内容:

Reads the next byte of data from the input stream. The value byte is returned as an int in the range 0 to 255.

我的想法是:只有 255 个不同的字符可能吗?一定是推理有误,因为在我的源码中使用了哪些字符并不重要。

所以 - 谁能帮我做这个脑筋急转弯?非常感谢。

需要 2 个字节的字符包含一个标志(在第一个字节中),通知任何想知道的人(包括文本编辑器)它需要另一个字节。

在你的例子中,你读取了第一个字节作为一个整体,包括标志,然后它读取了第二个字节。附加它们的是文本编辑器或控制台。

将字符转换为字节(反之亦然)的过程称为 "character encoding"。它可以通过许多不同的方式来完成。这些转换的规则包含在 Java 所谓的 Charset. And Java supports many of them: ASCII, UTF_8, UTF_16, ISO_8859_1, etc. The standardones can be found in StandardCharsets.

一些字符集认为字节和字符之间是一对一的映射。 ISO_8859_1(又称 latin-1)就是其中之一。但是当然有一个缺点:使用这样的字符集只能将 256 个字符编码为字节(ISO_8859_1 的西方拉丁字符)。

其他一些,如 UTF_8,每个字符使用一个、两个或更多字节,具体取决于字符。 ASCII 字符(a-b、A-B、数字等)在单个字节上编码,而其他字符(重音字母、中文、西里尔文和其他字母)使用两个或更多字节。缺点是编码和解码比较困难,但优点是巨大的:这种编码支持所有可能的Unicode字符。

请记住,字节和字符是两种截然不同的东西,它们之间没有一对一的映射。使用 InputStreamReader 读取字符,使用 OutputStreamWriter 写入字符。始终指定一个字符集:不这样做将使用您的系统的默认编码(可能与另一个系统不同)。