如何使用Thread实现ScatterZipOutputStream?

时间:2019-02-15 12:16:43

标签: java java-ee

我实现了ScatterZipOutputStream以支持Zip64 >> How to implement Parallel Zip Creation with ScatterZipOutputStream with Zip64 Support?

现在,我正在尝试使用线程将其并行化。

这里是相同的代码,

文档说,

“多个线程可以写入自己的ScatterZipOutputStream实例,该实例将备份到文件或某种用户实现的存储形式(实现ScatterGatherBackingStore)。

线程完成后,他们可以使用writeTo方法将这些流连接在一起,成为一个完整的zip文件,该方法会将单个ScatterOutputStream写入目标ZipArchiveOutputStream。”

ref:https://commons.apache.org/proper/commons-compress/zip.html


class ParallelZipper extends Thread{
    private String sourceFolder;
    private String zipFilePath;
    private String fileTypesToBeAddedToZip;
    static ParallelScatterZipCreator scatterZipCreator = new ParallelScatterZipCreator();
    static ScatterZipOutputStream dirs;

    static {
        try {
            dirs = ScatterZipOutputStream.fileBased(File.createTempFile("java-zip-dirs", "tmp"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void run() 
    { 
        try
        { 
            System.out.println ("Thread " + 
                Thread.currentThread().getId() + 
                " is running"); 
            zip(sourceFolder, zipFilePath, fileTypesToBeAddedToZip);
        } 
        catch (Exception e) 
        { 
            // Throwing an exception 
            System.out.println ("Exception is caught"); 
        } 
    }

    public static void zip(String sourceFolder, String zipFilePath, String fileTypesToBeAddedToZip) throws IOException {
        OutputStream outputStream = null;
        ZipArchiveOutputStream zipArchiveOutputStream = null;
        try {

            File srcFolder = new File(sourceFolder);
            if (srcFolder.isDirectory()) {
                // uncomment following code if you want to add all files under srcFolder
                //Iterator<File> fileIterator = Arrays.asList(srcFolder.listFiles()).iterator();
                Iterator<File> fileIterator = FileUtils.iterateFiles(srcFolder, new String[]{fileTypesToBeAddedToZip}, true);

                File zipFile = new File(zipFilePath);
                zipFile.delete();
                outputStream = new FileOutputStream(zipFile);

                zipArchiveOutputStream = new ZipArchiveOutputStream(outputStream);
                zipArchiveOutputStream.setUseZip64(Zip64Mode.AsNeeded);

                int srcFolderLength = srcFolder.getAbsolutePath().length() + 1;  // +1 to remove the last file separator

                while (fileIterator.hasNext()) {
                    File file = fileIterator.next();

                    // uncomment following code if you want to add all files under srcFolder
                    //if (file.isDirectory()) {
                    //        continue;
                    //    }

                    String relativePath = file.getAbsolutePath().substring(srcFolderLength);

                    InputStreamSupplier streamSupplier =  new FileInputStreamSupplier(file);

                    ZipArchiveEntry zipArchiveEntry = new ZipArchiveEntry(relativePath);
                    zipArchiveEntry.setMethod(ZipEntry.DEFLATED);
                    scatterZipCreator.addArchiveEntry(zipArchiveEntry, streamSupplier);
                }
                scatterZipCreator.writeTo(zipArchiveOutputStream);
            }
            if (zipArchiveOutputStream != null) {
                zipArchiveOutputStream.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (outputStream != null) {
                outputStream.close();

            }
        }
    }

    static class FileInputStreamSupplier implements InputStreamSupplier {
        private File sourceFile;

        FileInputStreamSupplier(File sourceFile) {
            this.sourceFile = sourceFile;
        }

        @Override
        public InputStream get() {
            InputStream is = null;
            try {
                is = Files.newInputStream(sourceFile.toPath());
            } catch (IOException e) {
                e.printStackTrace();
            }
            return is;
        }

    }
    public String getZipFilePath() {
        return zipFilePath;
    }

    public void setZipFilePath(String zipFilePath) {
        this.zipFilePath = zipFilePath;
    }

    public String getSourceFolder() {
        return sourceFolder;
    }

    public void setSourceFolder(String sourceFolder) {
        this.sourceFolder = sourceFolder;
    }

    public String getFileTypesToBeAddedToZip() {
        return fileTypesToBeAddedToZip;
    }

    public void setFileTypesToBeAddedToZip(String fileTypesToBeAddedToZip) {
        this.fileTypesToBeAddedToZip = fileTypesToBeAddedToZip;
    } 
}

//Main Class 
public class ParallelZip 
{ 
    public static void main(String[] args) 
    { 
            ParallelZipper object = new ParallelZipper(); 
            String sourceFolder = "C:\\Users\\user\\Desktop\\ziptest\\";
            object.setSourceFolder(sourceFolder);

            String zipFilePath = "C:\\Users\\user\\Desktop\\ziptest\\Desk.zip";
            object.setZipFilePath(zipFilePath);

            String fileTypesToBeAddedToZip = "txt";
            object.setFileTypesToBeAddedToZip(fileTypesToBeAddedToZip);
            object.start(); 


            ParallelZipper object1 = new ParallelZipper(); 
            String sourceFolder1 = "C:\\Users\\user\\Desktop\\ziptest\\a\\";
            object1.setSourceFolder(sourceFolder1);

            object1.setZipFilePath(zipFilePath);

            object1.setFileTypesToBeAddedToZip(fileTypesToBeAddedToZip);
            object1.start();
    } 
} 

It should be able to process different directory parallely and create a single zip out of it.


0 个答案:

没有答案