How to split a huge zip file into multiple volumes?

前端 未结 4 1312
感情败类
感情败类 2020-12-03 08:37

When I create a zip Archive via java.util.zip.*, is there a way to split the resulting archive in multiple volumes?

Let\'s say my overall archive has

4条回答
  •  萌比男神i
    2020-12-03 08:59

    Check: http://saloon.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=38&t=004618

    I am not aware of any public API that will help you do that. (Although if you do not want to do it programatically, there are utilities like WinSplitter that will do it)

    I have not tried it but, every ZipEntry while using ZippedInput/OutputStream has a compressed size. You may get a rough estimate of the size of the zipped file while creating it. If you need 2MB of zipped files, then you can stop writing to a file after the cumulative size of entries become 1.9MB, taking .1MB for Manifest file and other zip file specific elements. So, in a nutshell, you can write a wrapper over the ZippedInputStream as follows:

    import java.util.zip.ZipOutputStream;
    import java.util.zip.ZipEntry;
    import java.io.FileOutputStream;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    
    public class ChunkedZippedOutputStream {
    
        private ZipOutputStream zipOutputStream;
    
        private String path;
        private String name;
    
        private long currentSize;
        private int currentChunkIndex;
        private final long MAX_FILE_SIZE = 16000000; // Whatever size you want
        private final String PART_POSTFIX = ".part.";
        private final String FILE_EXTENSION = ".zip";
    
        public ChunkedZippedOutputStream(String path, String name) throws FileNotFoundException {
            this.path = path;
            this.name = name;
            constructNewStream();
        }
    
        public void addEntry(ZipEntry entry) throws IOException {
            long entrySize = entry.getCompressedSize();
            if((currentSize + entrySize) > MAX_FILE_SIZE) {
                closeStream();
                constructNewStream();
            } else {
                currentSize += entrySize;
                zipOutputStream.putNextEntry(entry);
            }
        }
    
        private void closeStream() throws IOException {
            zipOutputStream.close();
        }
    
        private void constructNewStream() throws FileNotFoundException {
            zipOutputStream = new ZipOutputStream(new FileOutputStream(new File(path, constructCurrentPartName())));
            currentChunkIndex++;
            currentSize = 0;
        }
    
        private String constructCurrentPartName() {
            // This will give names is the form of .part.0.zip, .part.1.zip, etc.
            StringBuilder partNameBuilder = new StringBuilder(name);
            partNameBuilder.append(PART_POSTFIX);
            partNameBuilder.append(currentChunkIndex);
            partNameBuilder.append(FILE_EXTENSION);
            return partNameBuilder.toString();
        }
    }
    

    The above program is just a hint of the approach and not a final solution by any means.

提交回复
热议问题