zip压缩文件在linux、windows下中文名乱码

1、压缩代码

package com.common.utils;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
//import java.util.zip.ZipEntry; // 中文乱码
import java.util.zip.ZipInputStream;

import org.apache.tools.zip.ZipEntry;
//import java.util.zip.ZipOutputStream;
import org.apache.tools.zip.ZipOutputStream; // 中文乱码
public class ZipUtils {

    /**

     * 使用gzip进行压缩
     */
    public static String gzipString(String primStr) {
        if (primStr == null || primStr.length() == 0) {
            return primStr;
        }

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        GZIPOutputStream gzip=null;
        try {
            gzip = new GZIPOutputStream(out);
            gzip.write(primStr.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(gzip!=null){
                try {
                    gzip.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        return new sun.misc.BASE64Encoder().encode(out.toByteArray());
    }

    /**
     *
     * <p>Description:使用gzip进行解压缩</p>
     * @param compressedStr
     * @return
     */
    public static String gunzipString(String compressedStr){
        if(compressedStr==null){
            return null;
        }

        ByteArrayOutputStream out= new ByteArrayOutputStream();
        ByteArrayInputStream in=null;
        GZIPInputStream ginzip=null;
        byte[] compressed=null;
        String decompressed = null;
        try {
            compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
            in=new ByteArrayInputStream(compressed);
            ginzip=new GZIPInputStream(in);

            byte[] buffer = new byte[1024];
            int offset = -1;
            while ((offset = ginzip.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed=out.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ginzip != null) {
                try {
                    ginzip.close();
                } catch (IOException e) {
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }

        return decompressed;
    }

    /**
     * 使用zip进行压缩
     * @param str 压缩前的文本
     * @return 返回压缩后的文本
     */
    public static final String zipString(String str) {
        if (str == null)
            return null;
        byte[] compressed;
        ByteArrayOutputStream out = null;
        ZipOutputStream zout = null;
        String compressedStr = null;
        try {
            out = new ByteArrayOutputStream();
            zout = new ZipOutputStream(out);
            zout.putNextEntry(new ZipEntry("0"));
            zout.write(str.getBytes());
            zout.closeEntry();
            compressed = out.toByteArray();
            compressedStr = new sun.misc.BASE64Encoder().encodeBuffer(compressed);
        } catch (IOException e) {
            compressed = null;
        } finally {
            if (zout != null) {
                try {
                    zout.close();
                } catch (IOException e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }
        return compressedStr;
    }

    /**
     * 使用zip进行解压缩
     * @param compressedStr 压缩后的文本
     * @return 解压后的字符串
     */
    public static final String unzipString(String compressedStr) {
        if (compressedStr == null) {
            return null;
        }

        ByteArrayOutputStream out = null;
        ByteArrayInputStream in = null;
        ZipInputStream zin = null;
        String decompressed = null;
        try {
            byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr);
            out = new ByteArrayOutputStream();
            in = new ByteArrayInputStream(compressed);
            zin = new ZipInputStream(in);
            zin.getNextEntry();
            byte[] buffer = new byte[1024];
            int offset = -1;
            while ((offset = zin.read(buffer)) != -1) {
                out.write(buffer, 0, offset);
            }
            decompressed = out.toString();
        } catch (IOException e) {
            decompressed = null;
        } finally {
            if (zin != null) {
                try {
                    zin.close();
                } catch (IOException e) {
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }
        return decompressed;
    }

    // 压缩
    public static String compressString(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        gzip.write(str.getBytes());
        gzip.close();
        return out.toString("UTF-8");
    }

    // 解压缩
    public static String uncompressString(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(str
                .getBytes("UTF-8"));
        GZIPInputStream gunzip = new GZIPInputStream(in);
        byte[] buffer = new byte[256];
        int n;
        while ((n = gunzip.read(buffer)) <= 0) {
            out.write(buffer, 0, n);
        }
        // toString()使用平台默认编码,也可以显式的指定如toString("GBK")
        return out.toString();
    }

    public static void main(String[] args) throws IOException {
//        System.out.println(gzip(str));
//        System.out.println(gzip(str).length());
//        System.out.println(zip(str).length());
//
//        System.out.println(gunzip(gzip(str)).length());
//        System.out.println(unzip(zip(str)).length());
//
//        //测试字符串
//        str="%5B%7B%22lastUpdateTime%22%3A%222011-10-28+9%3A39%3A41%22%2C%22smsList%22%3A%5B%7B%22liveState%22%3A%221";
//        System.out.println("原长度:"+str.length());
//        System.out.println("压缩后:"+compressString(str).length());
//        System.out.println("解压缩:"+uncompressString(compressString(str)));


    }

    /**
     *
     * 文件打包下载
     *
     * @param files
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    public static HttpServletResponse downLoadFiles(List<File> files, HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        try {
            /**这个集合就是你想要打包的所有文件,
             * 这里假设已经准备好了所要打包的文件*/
            //List<File> files = new ArrayList<File>();

            /**创建一个临时压缩文件,
             * 我们会把文件流全部注入到这个文件中
             * 这里的文件你可以自定义是.rar还是.zip
             **/
            String rootPath = request.getSession().getServletContext().getRealPath("") + File.separator
                    + Constant.UPLOAD_IMAGE_FOLDER + File.separator
                    + "qrcode_temp_zip" + File.separator
                    + CommonUtil.getSessionUserTenantId(request) + File.separator
                    + "qrcode.zip";
            File file = new File(rootPath);
            if (!file.exists()){
                file.getParentFile().mkdirs();
                file.createNewFile();
            }
            response.reset();
            //response.getWriter()
            //创建文件输出流
            FileOutputStream fous = new FileOutputStream(file);
            /**打包的方法我们会用到ZipOutputStream这样一个输出流,
             * 所以这里我们把输出流转换一下*/
//            org.apache.tools.zip.ZipOutputStream zipOut
//                = new org.apache.tools.zip.ZipOutputStream(fous);
            ZipOutputStream zipOut = new ZipOutputStream(fous);
            String agent = request.getHeader("user-agent");
            boolean isWindows = agent.toLowerCase().contains("windows");
            if(isWindows) {
                zipOut.setEncoding("gbk");//设置的和文件名字格式一样或开发环境编码设置一样的话就能正常显示了
            }
            /**这个方法接受的就是一个所要打包文件的集合,
             * 还有一个ZipOutputStream*/
            zipFile(files, zipOut);
            zipOut.close();
            fous.close();
            return downloadZip(file,response);
        }catch (Exception e) {
            e.printStackTrace();
        }
        /**直到文件的打包已经成功了,
         * 文件的打包过程被我封装在FileUtil.zipFile这个静态方法中,
         * 稍后会呈现出来,接下来的就是往客户端写数据了*/
        // OutputStream out = response.getOutputStream();


        return response ;
    }

    /**
     * 把接受的全部文件打成压缩包
     *
     * @param files
     * @param outputStream
     */
    public static void zipFile(List files, ZipOutputStream outputStream) {
        int size = files.size();
        for(int i = 0; i < size; i++) {
            File file = (File) files.get(i);
            zipFile(file, outputStream);
        }
    }

    public static HttpServletResponse downloadZip(File file, HttpServletResponse response) {
        try {
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(file.getPath()));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            // 清空response
            response.reset();

            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + file.getName());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }finally{
            try {
                File f = new File(file.getPath());
                f.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }

    /**
     * 根据输入的文件与输出流对文件进行打包
     * @param inputFile
     * @param ouputStream
     */
    public static void zipFile(File inputFile, ZipOutputStream ouputStream) {
        try {
            if(inputFile.exists()) {
                /**如果是目录的话这里是不采取操作的,
                 * 至于目录的打包正在研究中*/
                if (inputFile.isFile()) {
                    FileInputStream IN = new FileInputStream(inputFile);
                    BufferedInputStream bins = new BufferedInputStream(IN, 512);
                    //org.apache.tools.zip.ZipEntry
                    ZipEntry entry = new ZipEntry(inputFile.getName());
                    ouputStream.putNextEntry(entry);
                    // 向压缩文件中输出数据
                    int nNumber;
                    byte[] buffer = new byte[512];
                    while ((nNumber = bins.read(buffer)) != -1) {
                        ouputStream.write(buffer, 0, nNumber);
                    }
                    // 关闭创建的流对象
                    bins.close();
                    IN.close();
                } else {
                    try {
                        File[] files = inputFile.listFiles();
                        for (int i = 0; i < files.length; i++) {
                            zipFile(files[i], ouputStream);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 下载网络图片保存到本地
    public static void downloadByUrl(final String urlString,final String filename, final String savePath) throws InterruptedException {
        Thread trhead = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    // 构造URL
                    URL url = new URL(urlString);
                    System.out.println(urlString);
                    System.out.println(urlString.length());
                    System.out.println("------------------------------");
                    // 打开连接
                    URLConnection con = url.openConnection();
                    //设置请求超时为5s
                    con.setConnectTimeout(10*1000);
                    // 输入流
                    InputStream is = con.getInputStream();

                    // 1K的数据缓冲
                    byte[] bs = new byte[1024];
                    // 读取到的数据长度
                    int len;
                    // 输出的文件流
                    File sf=new File(savePath);
                    if(!sf.exists()){
                        sf.mkdirs();
                    }
                    OutputStream os = new FileOutputStream(sf.getPath() + File.separator + filename);
                    // 开始读取
                    while ((len = is.read(bs)) != -1) {
                        os.write(bs, 0, len);
                    }
                    // 完毕,关闭所有链接
                    os.close();
                    is.close();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        });
        trhead.start();
        trhead.join();
    }

    public static void download(String url, String filePathName) {
        HttpClient httpclient = new DefaultHttpClient();
        try {
            HttpGet httpget = new HttpGet(url);

            //伪装成google的爬虫JAVA问题查询
            httpget.setHeader("User-Agent", "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)");
            // Execute HTTP request
            System.out.println("executing request " + httpget.getURI());
            HttpResponse response = httpclient.execute(httpget);

            File storeFile = new File(filePathName);
            FileOutputStream output = new FileOutputStream(storeFile);

            // 得到网络资源的字节数组,并写入文件
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream instream = entity.getContent();
                try {
                    byte b[] = new byte[1024];
                    int j = 0;
                    while( (j = instream.read(b))!=-1){
                        output.write(b,0,j);
                    }
                    output.flush();
                    output.close();
                } catch (IOException ex) {
                    // In case of an IOException the connection will be released
                    // back to the connection manager automatically
                    throw ex;
                } catch (RuntimeException ex) {
                    // In case of an unexpected exception you may want to abort
                    // the HTTP request in order to shut down the underlying
                    // connection immediately.
                    httpget.abort();
                    throw ex;
                } finally {
                    // Closing the input stream will trigger connection release
                    try { instream.close(); } catch (Exception ignore) {}
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpclient.getConnectionManager().shutdown();
        }
    }
}

2、需要注意的问题

第一:使用

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
这两个包在ant-1.6.5.jar中

第二:通过客户端判断请求的系统环境,如果是windows需要设置编码格式为gbk

ZipOutputStream zipOut = new ZipOutputStream(fous);
            String agent = request.getHeader("user-agent");
            boolean isWindows = agent.toLowerCase().contains("windows");
            if(isWindows) {
                zipOut.setEncoding("gbk");//设置的和文件名字格式一样或开发环境编码设置一样的话就能正常显示了
            }





你可能感兴趣的:(zip压缩文件在linux、windows下中文名乱码)