更新時(shí)間:2022-04-29 10:30:34 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1921次
動(dòng)力節(jié)點(diǎn)小編來(lái)給大家講一下Java解析文件亂碼問(wèn)題。
普通的文件是指我們平時(shí)用記事本可以看到內(nèi)容的文件,例如.txt結(jié)尾的文件,這里為了測(cè)試,小編準(zhǔn)備了了兩個(gè)編碼的文件,test.txt和test2.txt,test.txt是通過(guò)window創(chuàng)建的文件編碼是 GBK,test2.txt是在編輯器里創(chuàng)建的,編輯器的編碼是 UTF-8;
文件內(nèi)容如下:
test.txt
test2.txt
方式一 :字節(jié)流讀取字節(jié)轉(zhuǎn)化為字符串顯示
//通過(guò)FileInputStream讀取字節(jié)
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("使用默認(rèn)編碼-----------------------------");
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("使用默認(rèn)編碼-----------------------------");
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是封裝的工具類(lèi),其實(shí)里面使用的就是apache的IOUtils,這里不進(jìn)行累述。
代碼讀取了兩個(gè)文件,執(zhí)行結(jié)果如下:
****************************讀取test1.txt文件 start *****************************
使用默認(rèn)編碼-----------------------------
111????
使用UTF-8編碼-----------------------------
111????
使用GBK編碼-----------------------------
111測(cè)試
使用GB2312編碼-----------------------------
111測(cè)試
使用ISO-8859-1編碼-----------------------------
1112aê?
****************************讀取test1.txt文件 end *****************************
****************************讀取test2.txt文件 start *****************************
使用默認(rèn)編碼-----------------------------
?##=====Set Dubbo Begin=====
## Dubbo注冊(cè)中心地址
使用UTF-8編碼-----------------------------
?##=====Set Dubbo Begin=====
## Dubbo注冊(cè)中心地址
使用GBK編碼-----------------------------
锘?##=====Set Dubbo Begin=====
## Dubbo娉ㄥ唽涓績(jī)鍦板潃
使用GB2312編碼-----------------------------
锘?##=====Set Dubbo Begin=====
## Dubbo娉ㄥ??涓?蹇??板??
使用ISO-8859-1編碼-----------------------------
???##=====Set Dubbo Begin=====
## Dubbo?3¨?????-?????°??€
****************************讀取test2.txt文件 end *****************************
結(jié)果顯而易見(jiàn),編碼不同出現(xiàn)中文亂碼,這里亂碼的原因是因?yàn)?new String()。java在字節(jié)轉(zhuǎn)化為字符時(shí)不指定編碼則會(huì)使用默認(rèn)編碼,我的編輯器默認(rèn)編碼是 UTF-8,所以出現(xiàn)上面的結(jié)果。
方式二 : 字符流讀取字符顯示
//通過(guò)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("以字符為單位讀取文件內(nèi)容,一次讀多個(gè)字節(jié):");
// 一次讀多個(gè)字符
char[] tempchars = new char[30];
int charread = 0;
reader1 = new InputStreamReader(new FileInputStream(path1));
System.out.println("使用默認(rèn)編碼(UTF-8):");
// 讀入多個(gè)字符到字符數(shù)組中,charread為一次讀取字符數(shù)
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;
// 讀入多個(gè)字符到字符數(shù)組中,charread為一次讀取字符數(shù)
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,執(zhí)行結(jié)果如下:
以字符為單位讀取文件內(nèi)容,一次讀多個(gè)字節(jié):
使用默認(rèn)編碼(UTF-8):
111????
使用GBK編碼:
111測(cè)試
顯然,和上面是一樣的,需要對(duì)應(yīng)編碼
字節(jié)文件一般來(lái)說(shuō)是要對(duì)應(yīng)的工具才能打開(kāi)的,用記事本打開(kāi)也看不到什么信息。
這里小編將之前的兩個(gè)文件加入到壓縮文件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工具類(lèi)進(jìn)行壓縮,讀取文件轉(zhuǎn)換為字節(jié)數(shù)組使用的是apache的工具類(lèi)。
執(zhí)行后的結(jié)果是Desktop2.rar中的中文存在亂碼,其他的正常。
如果對(duì)壓縮文件進(jìn)行再壓縮時(shí),第二種方法出來(lái)的壓縮文件不會(huì)有問(wèn)題,但是打開(kāi)里面的壓縮文件會(huì)提示損壞。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)