- Java读取文件时,可以使用文件流;若文件格式为csv,也可以使用opencsv等库进行读写。但是在涉及到中文时,常常出现乱码问题,这是由于文件的编码和读取时使用的文件流的编码不一致导致的。
- 涉及中文时,我们通常使用“UTF-8”,“gbk”等常见的编码格式进行文件的存储。正常情况下,是可以顺利存取的。但是在特殊情况如所使用的wps、excel版本问题,存取、另存、修改后保存等操作后,文件编码改变,且不为常见的“UTF-8”,“gbk”等格式,代码读取时则会出现乱码现象。
- 在网络上搜索并研究后,我发现了一种万全的解决方法:读取时检测文件的编码类型,使用该编码类型进行文件流的初始化,后续进行文件的读写时,编码则固定为原来格式,且可以适配所有可识别的编码,无需局限于常见的“UTF-8”,“gbk”等格式。
下面是相关样例
//此处的file为MultipartFile的对象,若为普通的file对象,则可以使用下面的getMultipartFile方法进行转换
// 解析文件
byte[] bytes = file.getBytes();
String encoding = getEncoding(bytes);
/**
* 获取文件编码类型
*
* @param bytes 文件bytes数组
* @return 编码类型
*/
public static String getEncoding(byte[] bytes) {
String defaultEncoding = "UTF-8";
UniversalDetector detector = new UniversalDetector(null);
detector.handleData(bytes, 0, bytes.length);
detector.dataEnd();
String encoding = detector.getDetectedCharset();
detector.reset();
if (encoding == null) {
encoding = defaultEncoding;
}
return encoding;
}
public static MultipartFile getMultipartFile(File file) {
FileItem item = new DiskFileItemFactory().createItem("file"
, MediaType.MULTIPART_FORM_DATA_VALUE
, true
, file.getName());
try (InputStream input = new FileInputStream(file);
OutputStream os = item.getOutputStream()) {
// 流转移
IOUtils.copy(input, os);
} catch (Exception e) {
throw new IllegalArgumentException("Invalid file: " + e, e);
}
return new CommonsMultipartFile(item);
}
在使用上面的方法获取到相关的文件编码后,存取文件时使用此编码进行即可,如下。
DataInputStream in = new DataInputStream(new FileInputStream(tempFile));
InputStreamReader inputStreamReader = new InputStreamReader(in, Charset.forName(encoding));
CSVReader csvReader = new CSVReader(inputStreamReader);
注意,这里可以不使用CSVReader,使用其他的读取方法,设定文件编码也是一样的。使用上述策略可以完全解决java开发中的文件中文乱码问题。