charset param在IOUtils.copy()中做了什么?

时间:2013-12-18 14:41:40

标签: java

我不是Java开发人员,但只需了解Java正在做什么。

我有一些代码IOUtils.copy(InputStream a, Writer b, "ISO-8859-1")或有效的话

此方法的文档说“inputEncoding - 用于输入流的编码,null表示平台默认值”。

据我所知,这只是说a预计将在ISO-8859-1中。它没有进行任何转换?这有什么意义。如果输入流被编码为UTF-8会发生什么?

5 个答案:

答案 0 :(得分:2)

  

据我所知,这只是说a预计会出现在ISO-8859-1中。

嗯,它期望a引用的流中的数据是ISO-8859-1中编码的文本数据。

  

它没有进行任何转换?

是的。它将从流中读取的二进制数据解释为给定编码中的文本,然后将文本数据写入编写器。 (至少,考虑到方法名称,这就是我的假设。)

  

如果输入流编码为UTF-8会发生什么?

如果数据实际上是以UTF-8编码的文本数据,那么伪造的数据将被写入作者(b)。每个字节都将转换为一个字符(因为ISO-8859-1每个字符有一个字节),然后该字符将被写入编写器。如果数据包含一个以UTF-8编码为多个字节的字符,则编写者将收到该单个原始字符的多个字符。

基本上,如果编码错误,数据很容易出现乱码。这就像尝试播放WAV文件一样,就好像它是一个MP3文件一样 - 除非没有保护措施,使得明显在这种情况下被打破......

答案 1 :(得分:1)

文本在计算机中由对(字节,编码)表示。您提到的API混合了InputStream API,该API针对所有字节流(不仅包括文本,也包括PNG图像,或ZIP存档,其中包含read(byte[] b)等方法)和{{3 API,而是处理String(实际上有像write(String)

这样的方法

该方法必须知道如何从字节流构建String,这就是charset参数的用途。如果未指定一个,则假定平台的默认字符集,但是当您想要从字节流构建文本时,总是需要字符集。当使用不同的字符集进行反序列化时,给定的字节数组可能表示不同的文本。

答案 2 :(得分:1)

Java有两种I / O类/接口:Streams(InputStreamOutputStream)和Readers / Writers

Streams 用于读取和写入二进制数据(字节)。 读者作家用于阅读和撰写文字(字符)。

需要使用character encoding将字符从字节转换为字节。

您的IOUtils.copy方法需要知道如何解释InputStream中的字节,以将其转换为可写入Writer的字符。

如果InputStream包含您提供的字符集中无效的字节序列,则可能会产生奇怪的效果(例如,编写奇怪的字符)。

答案 3 :(得分:0)

writer不只是一个字节流,它处理字符和字符串,这就是copy函数需要一个字符集的原因,从输入流构建阅读器以便读取字符。

这是传递作者时的copy实现:

1124    public static long More ...copyLarge(Reader input, Writer output) throws IOException {
1125        char[] buffer = new char[DEFAULT_BUFFER_SIZE];
1126        long count = 0;
1127        int n = 0;
1128        while (-1 != (n = input.read(buffer))) {
1129            output.write(buffer, 0, n);
1130            count += n;
1131        }
1132        return count;
1133    }

你看到它读取字符,只有你知道字符集才有可能(记住每个字符的字节数依赖于字符集)。

答案 4 :(得分:0)

CharSet告诉我们将InputStream给出的字节解释为表ISO-8859-1

给出的值

这是表值 ISO-8859-1