如何在Java中解压缩分割卷zip?

如何在Java中解压缩分割卷zip?,java,zip,Java,Zip,我需要重新组装一个包含100个部分的zip文件并提取内容。我尝试将zip卷简单地连接在一个输入流中,但这不起作用。如有任何建议,将不胜感激 谢谢。这是您可以开始的代码。它从多卷zip存档中提取单个文件条目: package org.test.zip; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOExce

我需要重新组装一个包含100个部分的zip文件并提取内容。我尝试将zip卷简单地连接在一个输入流中,但这不起作用。如有任何建议,将不胜感激


谢谢。

这是您可以开始的代码。它从多卷zip存档中提取单个文件条目:

package org.test.zip;

import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.SequenceInputStream;
import java.util.Arrays;
import java.util.Collections;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Main {

    public static void main(String[] args) throws IOException {
        ZipInputStream is = new ZipInputStream(new SequenceInputStream(Collections.enumeration(
            Arrays.asList(new FileInputStream("test.zip.001"), new FileInputStream("test.zip.002"), new FileInputStream("test.zip.003")))));
        try {
            for(ZipEntry entry = null; (entry = is.getNextEntry()) != null; ) {
                OutputStream os = new BufferedOutputStream(new FileOutputStream(entry.getName()));
                try {
                    final int bufferSize = 1024;
                    byte[] buffer = new byte[bufferSize];
                    for(int readBytes = -1; (readBytes = is.read(buffer, 0, bufferSize)) > -1; ) {
                        os.write(buffer, 0, readBytes);
                    }
                    os.flush();
                } finally {
                    os.close();
                }
            }
        } finally {
            is.close();
        }
    }
}

请注意,使其更具动态性--100%基于下面的mijer代码

    private void CombineFiles (String[] files) throws FileNotFoundException, IOException {
    Vector<FileInputStream> v = new Vector<FileInputStream>(files.length);
    for (int x = 0; x < files.length; x++)
        v.add(new FileInputStream(inputDirectory + files[x]));

    Enumeration<FileInputStream> e = v.elements();

    SequenceInputStream sequenceInputStream = new SequenceInputStream(e);

    ZipInputStream is = new ZipInputStream(sequenceInputStream);
    try {
        for (ZipEntry entry = null; (entry = is.getNextEntry()) != null;) {
            OutputStream os = new BufferedOutputStream(new FileOutputStream(entry.getName()));
            try {
                final int bufferSize = 1024;
                byte[] buffer = new byte[bufferSize];
                for (int readBytes = -1; (readBytes = is.read(buffer, 0, bufferSize)) > -1;) {
                    os.write(buffer, 0, readBytes);
                }
                os.flush();
            } finally {
                os.close();
            }
        }
    } finally {
        is.close();
    }

}
private void组合文件(字符串[]文件)抛出FileNotFoundException、IOException{
向量v=新向量(files.length);
用于(int x=0;x-1;){
写操作(缓冲区,0,读取字节);
}
os.flush();
}最后{
os.close();
}
}
}最后{
is.close();
}
}

仅连接段数据对我不起作用。在本例中,段是使用Linux命令行zip(InfoZip版本3.0)创建的:

已创建名为
data.z01、data.z02、…、data.zip的段文件

第一段
data.z01
包含跨越签名0x08074b50,如PKWARE的Zip文件格式规范所述。这4个字节的存在使得Java ZipInputStream忽略了存档中的所有条目。与非拆分存档相比,最后一个段中的中央注册表还包含额外的段信息,但这不会导致ZipInputStream出现任何问题

我所要做的就是跳过跨越签名。下面的代码将从用
zip-s
分割的存档文件和由Linux
split
commad分割的zip文件中提取条目,如下所示:
split-d-b5Mdata.zip data.zip.
。代码是基于szhem的

public class ZipCat {
    private final static byte[] SPANNING_SIGNATURE = {0x50, 0x4b, 0x07, 0x08};

    public static void main(String[] args) throws IOException {
        List<InputStream> asList = new ArrayList<>();            
        byte[] buf4 = new byte[4];
        PushbackInputStream pis = new PushbackInputStream(new FileInputStream(args[0]), buf4.length);
        asList.add(pis);
        if (pis.read(buf4) != buf4.length) {
            throw new IOException(args[0] + " is too small for a zip file/segment");
        }
        if (!Arrays.equals(buf4, SPANNING_SIGNATURE)) {
            pis.unread(buf4, 0, buf4.length);
        }
        for (int i = 1; i < args.length; i++) {
            asList.add(new FileInputStream(args[i]));
        }

        try (ZipInputStream is = new ZipInputStream(new SequenceInputStream(Collections.enumeration(asList)))) {
            for (ZipEntry entry = null; (entry = is.getNextEntry()) != null;) {
                if (entry.isDirectory()) {
                    new File(entry.getName()).mkdirs();
                } else {
                    try (OutputStream os = new BufferedOutputStream(new FileOutputStream(entry.getName()))) {
                        byte[] buffer = new byte[1024];
                        int count = -1;
                        while ((count = is.read(buffer)) != -1) {
                            os.write(buffer, 0, count);
                        }
                    }
                }
            }
        }
    }
}
公共类ZipCat{
私有最终静态字节[]跨越_签名={0x50,0x4b,0x07,0x08};
公共静态void main(字符串[]args)引发IOException{
List asList=new ArrayList();
字节[]buf4=新字节[4];
PushbackInputStream pis=新的PushbackInputStream(新文件输入流(args[0]),buf4.length);
asList.add(pis);
如果(pis.read(buf4)!=buf4.length){
抛出新IOException(args[0]+“对于zip文件/段来说太小”);
}
if(!array.equals(buf4,跨越_签名)){
pis.未读(buf4,0,buf4.长度);
}
对于(int i=1;i
AFAIK ZIP格式不像RAR那样具有内置的拆分支持。如果您使用类似于
cat file.zip.001 file.zip.002的内容加入它们,会发生什么情况。。。file.zip.100 file.zip
然后使用zip实用程序将其解压缩?什么“不起作用”?您得到了什么错误或异常?@NullUserExceptionఠ_ఠ ZIP文件中的多卷支持已经有一段时间了,请参阅.Perfect中的V.General Format of a.ZIP文件。非常感谢你。
public class ZipCat {
    private final static byte[] SPANNING_SIGNATURE = {0x50, 0x4b, 0x07, 0x08};

    public static void main(String[] args) throws IOException {
        List<InputStream> asList = new ArrayList<>();            
        byte[] buf4 = new byte[4];
        PushbackInputStream pis = new PushbackInputStream(new FileInputStream(args[0]), buf4.length);
        asList.add(pis);
        if (pis.read(buf4) != buf4.length) {
            throw new IOException(args[0] + " is too small for a zip file/segment");
        }
        if (!Arrays.equals(buf4, SPANNING_SIGNATURE)) {
            pis.unread(buf4, 0, buf4.length);
        }
        for (int i = 1; i < args.length; i++) {
            asList.add(new FileInputStream(args[i]));
        }

        try (ZipInputStream is = new ZipInputStream(new SequenceInputStream(Collections.enumeration(asList)))) {
            for (ZipEntry entry = null; (entry = is.getNextEntry()) != null;) {
                if (entry.isDirectory()) {
                    new File(entry.getName()).mkdirs();
                } else {
                    try (OutputStream os = new BufferedOutputStream(new FileOutputStream(entry.getName()))) {
                        byte[] buffer = new byte[1024];
                        int count = -1;
                        while ((count = is.read(buffer)) != -1) {
                            os.write(buffer, 0, count);
                        }
                    }
                }
            }
        }
    }
}