项目场景:
上传附件
问题描述:
上传GBK编码格式文件时,系统报错Cause:java.sql.SQLException:Incorrect string value:'\xf1\xA3\xAC\xB2\xEF\xBF...' for column
原因分析:
系统默认UTF-8编码,数据库使用UTF-8编码。
GBK中文占用2个字节,UTF-8中文占用3个字节
上传GBK文件时产生乱码,乱码包含生僻字,个别生僻字占用四个字节导致保存到数据库时类型不匹配的错误。
解决方案:
第一种:
数据库编码格式修改为:utf8mb4
utf8mb4是utf8的扩展,支持4个字节中文。
第二种:
将上传的GBK文件转换为UTF-8文件再读取内容
File tmpFile = null;
//拿到文件流之后,判断是GBK文件 还是UTF-8
if(FileUtil.getFileEncode(zip.getInputStream(ze), zip.getInputStream(ze)).equalsIgnoreCase("GBK")){
//创建临时文件
String destFileName = System.getProperty("java.io.tmpdir") + System.getProperty("file.separator") + file.getName();
//将GBK文件转换为UTF-8文件存储
FileUtil.transferFileGbkToUtf8(zip.getInputStream(ze), destFileName);
tmpFile = new File(destFileName);
//读取转换后的UTF-8文件
inputStream = new FileInputStream(tmpFile);
}
/**
*判断是GBK文件 还是UTF-8
**/
public static String getFileEncode(InputStream inputStream1, InputStream inputStream2){
if(inputStream1 == null || inputStream2 == null){
return "";
}
BufferedReader reader1 = null;
int len1 = 0;
try {
reader1 = new BufferedReader(new InputStreamReader(inputStream1, "UTF-8"));
String str=reader1.readLine();
len1=str.length();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(reader1 != null){
reader1.close();
}
if(inputStream1 != null){
inputStream1.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedReader reader2 = null;
int len2 = 0;
try {
reader2 = new BufferedReader(new InputStreamReader(inputStream2, "GBK"));
String str=reader2.readLine();
len2=str.length();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if(reader2 != null){
reader2.close();
}
if(inputStream1 != null){
inputStream1.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
if(len1<=len2){
return "UTF-8";
}
else{
return "GBK";
}
}
/**
*GBK文件转换为UTF-8
**/
public static void transferFileGbkToUtf8(InputStream inputStream, String destFileName) {
if(inputStream==null){
return;
}
BufferedReader d = null;
Writer ow = null;
StringBuilder sb = new StringBuilder();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream,"GBK"));
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\r\n");
}
ow = new OutputStreamWriter(new FileOutputStream(destFileName), "utf-8");
ow.write(sb.toString());
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(ow!=null){
ow.close();
}
if(d!=null){
d.close();
}
if(inputStream!=null){
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}