HiSEN

Java 文件读取,部分中文乱码 - 分析与解决

一、背景

最近做项目有一个地址库文件需要放在后端
由于文件在 jar 包中的问题,一些读取文件的姿势失效(方便的 Guava Files)
最后通过 getResourceAsStream 解决

接下来遇到了一件奇怪的事情,部分汉字乱码了,
调整编码,重新编辑汉字都试过了,无法解决。

最后求助于百度搜索,得到了一些有效的信息。
汉字是两个字节的,如果每次读固定个字节,可能会把汉字截断,造成乱码。
再次印证了基础知识的重要性!

二、相关代码

2.1 罪魁祸首

利用缓冲区读取文件,会出现边界情况下把汉字分割成两次来读。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private static String getAddressJson(String path) throws IOException {
log.info("cacheFile start. PATH:{}", path);
InputStream resourceAsStream = Address.class.getClassLoader().getResourceAsStream(path);
StringBuilder sb = new StringBuilder();
byte[] buf = new byte[10240];
int length;

while ((length = Objects.requireNonNull(resourceAsStream).read(buf)) != -1) {
// 此处 new String 放进去了一半中文字符,导致乱码
sb.append(new String(buf, 0, length, StandardCharsets.UTF_8));
}
resourceAsStream.close();

return sb.toString();
}

2.2 完美运行

据说现在很多人没法纯手写通过流读取文件了…(说的就是我!)

1
2
3
4
5
6
7
8
9
10
11
12
13
private static String getAddressJson(String path) throws IOException {
log.info("cacheFile start. PATH:{}", path);
InputStream resourceAsStream = Address.class.getClassLoader().getResourceAsStream(path);
StringBuilder sb = new StringBuilder();
InputStreamReader isr = new InputStreamReader(Objects.requireNonNull(resourceAsStream));
BufferedReader br = new BufferedReader(isr);
String newLine;
while ((newLine = br.readLine()) != null) {
sb.append(newLine);
}
resourceAsStream.close();
return sb.toString();
}

三、参考文章

CSDN