【发布时间】:2021-09-23 15:26:48
【问题描述】:
我正在尝试验证我正在摄取的文件是否都严格符合 UTF8,并且通过我的几次阅读,我得出的结论是,如果要正确完成验证,数据的原始、未篡改字节必须进行分析。如果在事后尝试查看字符串本身,他们不太可能发现是否有任何字符不兼容 UTF8,因为 Java 会尝试转换它们。
我正在正常读取文件:我从文件中收到InputStream,然后将InputStreamReader 提供给它,然后将其提供给BufferedReader。它看起来像:
InputStream is = new FileInputStream(fileLocation);
InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8)));
BufferedReader br = new BufferedReader(isr);
我可以重写 BufferedReader 类,为它偶然发现的每个字符添加一些验证。
问题是BufferedReader 有一个char[],而不是byte[],用于缓冲区。这意味着字节会自动转换为字符。
所以,我的问题是:这个验证可以在 BufferedReader 中的char[] 级别完成吗?虽然我在这里有点“强制”UTF8:
InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8)));
我看到字符从非 utf-8(比如 utf-16)转换为 utf-8,并破坏了一些系统。我不知道 char[] 对于此验证而言基本上“为时已晚”。是吗?
【问题讨论】:
-
"可以在位于
BufferedReader的char[]级别完成此验证吗?" - 否。到那时,UTF-8 已经被解析并解码为char[]。如果出现问题,char[]将不会包含正确的字符。所以,你真的需要验证原来的byte[]。 -
@RemyLebeau 感谢您的回复!
-
嘿@RemyLebeau,我有一个问题。如果一个文件包含 UTF16 编码的字形,并且我将 BufferedReader 设置为使用 UTF8,我不会收到错误消息,并且当我调用
readLine()时,该值会以字符串的形式正常返回。这里发生了什么? -
我假设您的意思是
InputStreamReader而不是BufferedReader?BufferedReader将存储并返回InputStreamReader分配的字符集从将字节解码为字符输出的任何 UTF-16 代码单元。如果编码不匹配,可能会返回错误的字符,甚至会被省略。默认情况下,解码将返回'\uFFFD'字符以表示解码错误。如果您想更改该行为,请使用CharsetDecoder创建InputStreamReader,其malformedInput和unmappableCharacter操作已根据需要进行自定义。
标签: java utf-8 inputstream bufferedreader inputstreamreader