更新时间:2022-04-29 10:30:34 来源:极悦 浏览1538次
极悦小编来给大家讲一下Java解析文件乱码问题。
普通的文件是指我们平时用记事本可以看到内容的文件,例如.txt结尾的文件,这里为了测试,小编准备了了两个编码的文件,test.txt和test2.txt,test.txt是通过window创建的文件编码是 GBK,test2.txt是在编辑器里创建的,编辑器的编码是 UTF-8;
文件内容如下:
test.txt
test2.txt
方式一 :字节流读取字节转化为字符串显示
//通过FileInputStream读取字节
String path1 = "C:\\Users\\yanzhichao\\Desktop\\test.txt";
String path2 = "C:\\Users\\yanzhichao\\Desktop\\test2.txt";
InputStream inputStream1 = null;
InputStream inputStream2 = null;
try{
inputStream1 = new FileInputStream(path1);
byte[] bytes1 = T.IOUtils.toByteArray(inputStream1);
System.out.println("****************************读取test1.txt文件 start *****************************");
System.out.println("使用默认编码-----------------------------");
System.out.println(new String(bytes1));
System.out.println("使用UTF-8编码-----------------------------");
System.out.println(new String(bytes1,"UTF-8"));
System.out.println("使用GBK编码-----------------------------");
System.out.println(new String(bytes1,"GBK"));
System.out.println("使用GB2312编码-----------------------------");
System.out.println(new String(bytes1,"GB2312"));
System.out.println("使用ISO-8859-1编码-----------------------------");
System.out.println(new String(bytes1,"ISO-8859-1"));
System.out.println("****************************读取test1.txt文件 end *****************************");
inputStream2 = new FileInputStream(path2);
byte[] bytes2 = T.IOUtils.toByteArray(inputStream2);
System.out.println("****************************读取test2.txt文件 start *****************************");
System.out.println("使用默认编码-----------------------------");
System.out.println(new String(bytes2));
System.out.println("使用UTF-8编码-----------------------------");
System.out.println(new String(bytes2,"UTF-8"));
System.out.println("使用GBK编码-----------------------------");
System.out.println(new String(bytes2,"GBK"));
System.out.println("使用GB2312编码-----------------------------");
System.out.println(new String(bytes2,"GB2312"));
System.out.println("使用ISO-8859-1编码-----------------------------");
System.out.println(new String(bytes2,"ISO-8859-1"));
System.out.println("****************************读取test2.txt文件 end *****************************");
} catch (Exception e) {
e.printStackTrace();
} finally {
if(inputStream1 != null) {
try {
inputStream1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码中T.IOUtils.toByteArray是封装的工具类,其实里面使用的就是apache的IOUtils,这里不进行累述。
代码读取了两个文件,执行结果如下:
****************************读取test1.txt文件 start *****************************
使用默认编码-----------------------------
111����
使用UTF-8编码-----------------------------
111����
使用GBK编码-----------------------------
111测试
使用GB2312编码-----------------------------
111测试
使用ISO-8859-1编码-----------------------------
111²âÊÔ
****************************读取test1.txt文件 end *****************************
****************************读取test2.txt文件 start *****************************
使用默认编码-----------------------------
##=====Set Dubbo Begin=====
## Dubbo注册中心地址
使用UTF-8编码-----------------------------
##=====Set Dubbo Begin=====
## Dubbo注册中心地址
使用GBK编码-----------------------------
锘�##=====Set Dubbo Begin=====
## Dubbo娉ㄥ唽涓績鍦板潃
使用GB2312编码-----------------------------
锘�##=====Set Dubbo Begin=====
## Dubbo娉ㄥ��涓�蹇��板��
使用ISO-8859-1编码-----------------------------
##=====Set Dubbo Begin=====
## Dubbo注册ä¸å¿ƒåœ°å€
****************************读取test2.txt文件 end *****************************
结果显而易见,编码不同出现中文乱码,这里乱码的原因是因为 new String()。java在字节转化为字符时不指定编码则会使用默认编码,我的编辑器默认编码是 UTF-8,所以出现上面的结果。
方式二 : 字符流读取字符显示
//通过InputStreamReader读取字符
String path1 = "C:\\Users\\yanzhichao\\Desktop\\test.txt";
String path2 = "C:\\Users\\yanzhichao\\Desktop\\test2.txt";
InputStreamReader reader1 = null;
InputStreamReader reader2 = null;
try{
System.out.println("以字符为单位读取文件内容,一次读多个字节:");
// 一次读多个字符
char[] tempchars = new char[30];
int charread = 0;
reader1 = new InputStreamReader(new FileInputStream(path1));
System.out.println("使用默认编码(UTF-8):");
// 读入多个字符到字符数组中,charread为一次读取字符数
while ((charread = reader1.read(tempchars)) != -1) {
// 同样屏蔽掉\r不显示
if ((charread == tempchars.length)
&& (tempchars[tempchars.length - 1] != '\r')) {
System.out.print(tempchars);
} else {
for (int i = 0; i < charread; i++) {
if (tempchars[i] == '\r') {
continue;
} else {
System.out.print(tempchars[i]);
}
}
}
}
System.out.println();
reader2 = new InputStreamReader(new FileInputStream(path1),"GBK");
System.out.println("使用GBK编码:");
tempchars = new char[30];
charread = 0;
// 读入多个字符到字符数组中,charread为一次读取字符数
while ((charread = reader2.read(tempchars)) != -1) {
// 同样屏蔽掉\r不显示
if ((charread == tempchars.length)
&& (tempchars[tempchars.length - 1] != '\r')) {
System.out.print(tempchars);
} else {
for (int i = 0; i < charread; i++) {
if (tempchars[i] == '\r') {
continue;
} else {
System.out.print(tempchars[i]);
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader1 != null) {
try {
reader1.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(reader2 != null) {
try {
reader2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
代码只读取了test.txt,执行结果如下:
以字符为单位读取文件内容,一次读多个字节:
使用默认编码(UTF-8):
111����
使用GBK编码:
111测试
显然,和上面是一样的,需要对应编码
字节文件一般来说是要对应的工具才能打开的,用记事本打开也看不到什么信息。
这里小编将之前的两个文件加入到压缩文件Desktop.rar中,代码如下:
String path1 = "C:\\Users\\yanzhichao\\Desktop\\test.txt";
String path2 = "C:\\Users\\yanzhichao\\Desktop\\test2.txt";
String zipName = "C:\\Users\\yanzhichao\\Desktop\\Desktop.rar";
String zipName2 = "C:\\Users\\yanzhichao\\Desktop\\Desktop2.rar";
String folderName = "test";
List<String> filePathList = new ArrayList<>();
filePathList.add(path1);
filePathList.add(path2);
InputStream is = null;
InputStream is2 = null;
ZipFile zip = null;
ZipFile zip2 = null;
try {
//方法一
zip = new ZipFile(zipName);
ZipParameters para = null;
File file = null;
for (String fliePath : filePathList) {
file = new File(fliePath);
para = new ZipParameters();
para.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
para.setFileNameInZip(folderName+ fliePath.substring(fliePath.lastIndexOf(File.separator)));
para.setSourceExternalStream(true);
is = new ByteArrayInputStream(T.FileUtils.readFileToByteArray(file));
zip.addStream(is, para);
}
//方法二
zip2 = new ZipFile(zipName2);
ZipParameters para2 = null;
for (String fliePath : filePathList) {
String content = new String(T.IOUtils.toByteArray(new FileInputStream(fliePath)));
para2 = new ZipParameters();
para2.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
para2.setFileNameInZip(folderName+ fliePath.substring(fliePath.lastIndexOf(File.separator)));
para2.setSourceExternalStream(true);
is2 = new ByteArrayInputStream(content.getBytes());
zip2.addStream(is2, para2);
}
} catch (ZipException | IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is2 != null) {
try {
is2.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
代码中使用了zip4j工具类进行压缩,读取文件转换为字节数组使用的是apache的工具类。
执行后的结果是Desktop2.rar中的中文存在乱码,其他的正常。
如果对压缩文件进行再压缩时,第二种方法出来的压缩文件不会有问题,但是打开里面的压缩文件会提示损坏。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习