时间:2018-7-31
现象:项目在本地启动下载文件压缩后,没有出现乱码问题,但在docker容器中部署项目后,写出文件压缩后中文乱码
解决过程: 首先在代码中尝试了多种写出方法。因为有文件需要压缩,使用最java自带工具类java.util.zip,出现了乱码(乱码为???)。此时想到的肯定是自己java编码压缩有问题,然后又换成了org.apache.tools.zip还是乱码,那我就想了啊,是不是在压缩前生成文件时就乱码了呢?
一看文件果然是输出文件时文件名就已经乱码了,此时想到的就是Java 的系统属性 sun.jnu.encoding 的编码问题,然后在系统中打印出来,如图,系统编码为ANSI_X3.4-1968,
顿时感觉问题有希望解决了,在输出文件之前添加了System.setProperty("sun.jnu.encoding","utf-8");此时再打印出来
虽然已经改成了utf-8但是文件输出的还是乱码,这时候真的很尴尬了,试过很多方法从代码下手试过很多方法依旧不行,此时心里严重怀疑是机器问题,上网查询了一下关于docker编码的问题,发现大家的却经常碰到docker中文编码错误,想去找dockerfile文件看一下,然而怎么找都找不到,问管服务器的人,那人也不吊我,实在没办法硬着头皮让那人换了一个docker镜像(换的这个dokcer镜像是其他项目使用的,文件写出没有问题),然后!然后就好了!此时再去看看java的系统变量编码sun.jnu.encoding就成了utf-8。
虽然已经改成了utf-8但是文件输出的还是乱码,这时候真的很尴尬了,试过很多方法从代码下手试过很多方法依旧不行,此时心里严重怀疑是机器问题,上网查询了一下关于docker编码的问题,发现大家的却经常碰到docker中文编码错误,想去找dockerfile文件看一下,然而怎么找都找不到,问管服务器的人,那人也不吊我,实在没办法硬着头皮让那人换了一个docker镜像(换的这个dokcer镜像是其他项目使用的,文件写出没有问题),然后!然后就好了!此时再去看看java的系统变量编码sun.jnu.encoding就成了utf-8。
果然还是系统编码问题,大家以后还是要相信自己的判断啊!当然前提是要从自身开始找问题,若尝试过各种方法还是不行,就要换一个思路去解决了!不能走进死胡同!
附文件压缩代码:
package test;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class ZipTest1 {
public static void main(String[] args){
String sysDir = System.getProperty("user.home")+"/测试文件夹";
System.out.println(sysDir);
String txtFileName = new String("测试文本.txt");
String txtContent = new String("测试文本内容");
System.out.println("sun.jnu.encoding"+System.getProperty("sun.jnu.encoding"));
File fileDir = new File(sysDir);
if(!fileDir.exists()){
fileDir.mkdirs();
}
try {
OutputStreamWriter oStreamWriter = new OutputStreamWriter(new FileOutputStream(sysDir+File.separator+txtFileName), "utf-8");
oStreamWriter.append(txtContent);
oStreamWriter.flush();
oStreamWriter.close();
}catch (IOException e){
e.printStackTrace();
}
try {
//压缩文件夹以及文件内容
FileOutputStream fos = new FileOutputStream(new File(sysDir + ".zip"));
ZipOutputStream zos = new ZipOutputStream(fos);
compressbyType(fileDir,zos,"" );
//记得关闭输出流
zos.close();
}catch (Exception e){
e.printStackTrace();
}
}
private static void compressbyType(File src, ZipOutputStream zos, String zipDir) {
if (!src.exists())
return;
System.out.println("压缩路径" + zipDir + src.getName());
//判断文件是否是文件,如果是文件调用compressFile方法,如果是路径,则调用compressDir方法;
if (src.isFile()) {
//src是文件,调用此方法
compressFile(src, zos, zipDir);
} else if (src.isDirectory()) {
//sr是文件夹,调用此方法
compressDir(src, zos, zipDir);
}
}
private static void compressFile(File file, ZipOutputStream zos,String zipDir) {
// String systemEncoding = System.getProperty("file.encoding");
if (!file.exists())
return;
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
// ZipEntry entry = new ZipEntry(baseDir + new String(file.getName().getBytes(systemEncoding),"UTF-8"));
ZipEntry entry = new ZipEntry(zipDir+file.getName());
zos.putNextEntry(entry);
int count;
byte[] buf = new byte[1024];
while ((count = bis.read(buf)) != -1) {
zos.write(buf, 0, count);
}
bis.close();
} catch (Exception e) {
// TODO: handle exception
}
}
private static void compressDir(File dir, ZipOutputStream zos,String zipDir) {
if (!dir.exists())
return;
File[] files = dir.listFiles();
if(files.length == 0){
try {
zos.putNextEntry(new ZipEntry(zipDir + dir.getName()+File.separator));
} catch (IOException e) {
e.printStackTrace();
}
}
for (File file : files) {
compressbyType(file, zos, zipDir + dir.getName() + File.separator);
}
}
}