導出zip壓縮包

圖片地址存在數據庫img 表裏。

查詢出文件地址filePath

調用工具類方法即可,上代碼:

List<EmplUserImag> emplUserImagList = emplUserImagService.selectByPrimaryKey(userIdList);
ArrayList<File> userPhotoFiles = new ArrayList<>();
for (EmplUserImag emplUserImag : emplUserImagList) {
    //用戶一寸照
    File userPhoto = new File(emplUserImag.getUserPhoto());
    userPhotoFiles.add(userPhoto);
}
ServletOutputStream sos = response.getOutputStream();
ZipUtils.toZip(userPhotoFiles, sos);

工具類:

package com.unicom.sh.pom.file.util;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/***
 * @Description:  
 * @Param:  
 * @return:  
 * @author: 楊舜璽
 * @create: 2019/1/7 16:51
 */

public class ZipUtils {

    private static final int  BUFFER_SIZE = 2 * 1024;

    /***
     * @Description:
     * @Param: [fileList, zipFile]
     * @return: void
     * @author: 多個文件壓縮
     * @create: 2019/1/7 13:28
     */

    public static void zipFiles(List<File> fileList,File zipFile) throws Exception{
        System.out.println("zipFiles待壓縮文件:"+zipFile.getAbsolutePath());
        if(fileList != null){
            if(zipFile.exists()){//壓縮文件已經存在,則只能單個添加
                for(File file:fileList){
                    zip(zipFile,file);
                }
            }else{//不存在則新建
                // 創建zip輸出流
                ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(zipFile), Charset.forName("UTF-8"));
                // 創建緩衝輸出流
                BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
                for(File file:fileList){
                    zipFile(file,zipOutStream,bufferOutStream);
                }
                //最後關閉輸出流
                bufferOutStream.close();
                zipOutStream.close();
            }

        }
    }

    /***
     * @Description:
     * @Param: [zipFile, sourceFile]
     * @return: void
     * @author: yangsx 單個文件壓縮
     * @create: 2019/1/7 13:26
     */

    public static void zip(File zipFile, File sourceFile) throws Exception {
        System.out.println("待壓縮文件:"+zipFile.getAbsolutePath());
        if (zipFile.exists()) {// 添加到已經存在的壓縮文件中

            File tempFile=new File(zipFile.getAbsolutePath()+".tmp");
            // 創建zip輸出流
            ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(tempFile), Charset.forName("UTF-8"));
            // 創建緩衝輸出流
            BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
            ZipFile zipOutFile = new ZipFile(zipFile);

            Enumeration<? extends ZipEntry> entries = zipOutFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                System.out.println("copy: " + entry.getName());
                zipOutStream.putNextEntry(entry);
                if (!entry.isDirectory()) {
                    write(zipOutFile.getInputStream(entry), bufferOutStream);
                }
                zipOutStream.closeEntry();
            }
            zipOutFile.close();//記得關閉zip文件,否則後面無法刪除原始文件
            ZipEntry entry = new ZipEntry(sourceFile.getName());
            // 添加實體
            zipOutStream.putNextEntry(entry);
            BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(sourceFile));
            write(bufferInputStream, bufferOutStream);
            //最後關閉輸出流
            bufferOutStream.close();
            zipOutStream.close();
            boolean flag=zipFile.delete();
            if(flag){
                tempFile.renameTo(zipFile);
            }else{
                System.out.println("刪除文件失敗。");
            }
        } else {// 新創建壓縮文件
            // 創建zip輸出流
            ZipOutputStream zipOutStream = new ZipOutputStream(new FileOutputStream(zipFile), Charset.forName("UTF-8"));
            // 創建緩衝輸出流
            BufferedOutputStream bufferOutStream = new BufferedOutputStream(zipOutStream);
            // 創建壓縮文件實體
            ZipEntry entry = new ZipEntry(sourceFile.getName());
            // 添加實體
            zipOutStream.putNextEntry(entry);
            // 創建輸入流
            BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(sourceFile));
            write(bufferInputStream, bufferOutStream);
            //最後關閉輸出流
            bufferOutStream.close();
            zipOutStream.close();
        }

    }

    /***
     * @Description:
     * @Param: [file, zipOutStream, bufferOutStream]
     * @return: void
     * @author: yangsx  執行文件壓縮
     * @create: 2019/1/7 13:24
     */

    private static void zipFile(File file,ZipOutputStream zipOutStream,BufferedOutputStream bufferOutStream) throws IOException{
        // 創建壓縮文件實體
        ZipEntry entry = new ZipEntry(file.getName());
        // 添加實體
        zipOutStream.putNextEntry(entry);
        // 創建輸入流
        BufferedInputStream bufferInputStream = new BufferedInputStream(new FileInputStream(file));
        write(bufferInputStream, bufferOutStream);
        zipOutStream.closeEntry();
    }

    /***
     * @Description:
     * @Param: [inputStream, outStream]
     * @return: void
     * @author: yangsx  讀寫zip文件
     * @create: 2019/1/7 13:25
     */

    private static void write(InputStream inputStream,OutputStream outStream) throws IOException{
        byte[] data=new byte[4096];
        int length=0;
        while((length=inputStream.read(data)) != -1){
            outStream.write(data,0,length);
        }
        outStream.flush();//刷新輸出流
        inputStream.close();//關閉輸入流
    }


    /**
     * 壓縮成ZIP 方法1
     * @param srcDir 壓縮文件夾路徑
     * @param out    壓縮文件輸出流
     * @param KeepDirStructure  是否保留原來的目錄結構,true:保留目錄結構;
     *                          false:所有文件跑到壓縮包根目錄下(注意:不保留目錄結構可能會出現同名文件,會壓縮失敗)
     * @an
     * @throws RuntimeException 壓縮失敗會拋出運行時異常
     */
    public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure)
            throws RuntimeException{
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure);
            long end = System.currentTimeMillis();
            System.out.println("壓縮完成,耗時:" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 壓縮成ZIP 方法2
     * @param srcFiles 需要壓縮的文件列表
     * @param out           壓縮文件輸出流
     * @throws RuntimeException 壓縮失敗會拋出運行時異常
     */
    public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[BUFFER_SIZE];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1){
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("壓縮完成,耗時:" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     94
     * 遞歸壓縮方法
     * @param sourceFile 源文件
     * @param zos        zip輸出流
     * @param name       壓縮後的名稱
     * @param KeepDirStructure  是否保留原來的目錄結構,true:保留目錄結構;
     *                          false:所有文件跑到壓縮包根目錄下(注意:不保留目錄結構可能會出現同名文件,會壓縮失敗)
     * @throws Exception
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name,
                                 boolean KeepDirStructure) throws Exception{
        byte[] buf = new byte[BUFFER_SIZE];
        if(sourceFile.isFile()){
            // 向zip輸出流中添加一個zip實體,構造器中name爲zip實體的文件的名字
            zos.putNextEntry(new ZipEntry(name));
            // copy文件到zip輸出流中
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1){
                zos.write(buf, 0, len);
            }
            // Complete the entry
            zos.closeEntry();
            in.close();
        } else {
            File[] listFiles = sourceFile.listFiles();
            if(listFiles == null || listFiles.length == 0){
                // 需要保留原來的文件結構時,需要對空文件夾進行處理
                if(KeepDirStructure){
                    // 空文件夾的處理
                    zos.putNextEntry(new ZipEntry(name + "/"));
                    // 沒有文件,不需要文件的copy
                    zos.closeEntry();
                }
            }else {
                for (File file : listFiles) {
                    // 判斷是否需要保留原來的文件結構
                    if (KeepDirStructure) {
                        // 注意:file.getName()前面需要帶上父文件夾的名字加一斜槓,
                        // 不然最後壓縮包中就不能保留原來的文件結構,即:所有文件都跑到壓縮包根目錄下了
                        compress(file, zos, name + "/" + file.getName(),KeepDirStructure);
                    } else {
                        compress(file, zos, file.getName(),KeepDirStructure);
                    }
                }
            }
        }
    }


    //文件複製
    public static void fileChannelCopy(String oldPath, String newPath) {
        File oldFile = new File(oldPath);
        File file = new File(newPath);
        FileInputStream in = null;
        FileOutputStream out = null;
        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            in = new FileInputStream(oldFile);
            out = new FileOutputStream(file);
            byte[] buffer=new byte[1024];
            int readByte = 0;
            while((readByte = in.read(buffer)) != -1){
                out.write(buffer, 0, readByte);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                in.close();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) throws Exception {
        /*Date date = new Date();
        String filePath = "C:\\Users\\Administrator\\Desktop\\"+date.getTime()+"\\";
        File file= new File(filePath);
        File files= new File(filePath+"files");
        //判斷是否存在
        if (!file.exists()) {
            file.mkdirs();
        }
        if (!files.exists()) {
            files.mkdirs();
        }
        ZipUtils.fileChannelCopy("C:\\Users\\Administrator\\Desktop\\bbb.pdf",
                filePath+"files\\bbb.pdf");*/


        ArrayList<File> files = new ArrayList<File>();
        File file1 = new File("C:/Users/sh-sangz/Desktop/sss/1.docx");
        File file2 = new File("C:/Users/sh-sangz/Desktop/sss/2.bmp");
        files.add(file1);
        files.add(file2);


        /** 測試壓縮方法1  */
        FileOutputStream fos1 = new FileOutputStream(new File("C:/Users/sh-sangz/Desktop/sss/1.zip"));
        ZipUtils.toZip(files, fos1);

    }




    /**
     * 替換某個 item,
     * @param zipInputStream zip文件的zip輸入流
     * @param zipOutputStream 輸出的zip輸出流
     * @param itemName 要替換的 item 名稱
     * @param itemInputStream 要替換的 item 的內容輸入流
     */
    public static void replaceItem(ZipInputStream zipInputStream,
                                   ZipOutputStream zipOutputStream,
                                   String itemName,
                                   InputStream itemInputStream
    ){
        //
        if(null == zipInputStream){return;}
        if(null == zipOutputStream){return;}
        if(null == itemName){return;}
        if(null == itemInputStream){return;}
        //
        ZipEntry entryIn;
        try {
            while((entryIn = zipInputStream.getNextEntry())!=null)
            {
                String entryName =  entryIn.getName();
                ZipEntry entryOut = new ZipEntry(entryName);
                // 只使用 name
                zipOutputStream.putNextEntry(entryOut);
                // 緩衝區
                byte [] buf = new byte[8*1024];
                int len;

                if(entryName.equals(itemName)){
                    // 使用替換流
                    while((len = (itemInputStream.read(buf))) > 0) {
                        zipOutputStream.write(buf, 0, len);
                    }
                } else {
                    // 輸出普通Zip流
                    while((len = (zipInputStream.read(buf))) > 0) {
                        zipOutputStream.write(buf, 0, len);
                    }
                }
                // 關閉此 entry
                zipOutputStream.closeEntry();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            //e.printStackTrace();
            close(itemInputStream);
            close(zipInputStream);
            close(zipOutputStream);
        }
    }

    /**
     * 包裝輸入流
     */
    public static ZipInputStream wrapZipInputStream(InputStream inputStream){
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        return zipInputStream;
    }

    /**
     * 包裝輸出流
     */
    public static ZipOutputStream wrapZipOutputStream(OutputStream outputStream){
        ZipOutputStream zipOutputStream = new ZipOutputStream(outputStream);
        return zipOutputStream;
    }
    private static void close(InputStream inputStream){
        if (null != inputStream){
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static void close(OutputStream outputStream){
        if (null != outputStream){
            try {
                outputStream.flush();
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章