Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Java中压缩文件和文件夹?_Java_Io_Compression_Zip_Fileinputstream - Fatal编程技术网

如何在Java中压缩文件和文件夹?

如何在Java中压缩文件和文件夹?,java,io,compression,zip,fileinputstream,Java,Io,Compression,Zip,Fileinputstream,请看下面的代码 public void startCompress(String path,String fileName,String outputLocation,int compressType,int filSize) throws Exception { System.out.println("Input Location: "+path); System.out.println("Output Location: "+outpu

请看下面的代码

public void startCompress(String path,String fileName,String outputLocation,int compressType,int filSize) throws Exception
    {        
        System.out.println("Input Location: "+path);
        System.out.println("Output Location: "+outputLocation);   

            System.out.println(compressType);
            byte[] bs=new byte[filSize];
            System.out.println(filSize);

            FileOutputStream fos=new FileOutputStream(outputLocation+"/test.zip");

            System.out.println(fos.toString());
            ZipOutputStream zos=new ZipOutputStream(fos);

            ZipEntry ze = new ZipEntry(fileName);

            zos.putNextEntry(ze);

            FileInputStream inputStream=new FileInputStream(path);

            int len;
            while((len=inputStream.read(bs))>0){
                zos.write(bs, 0, len);                
            }
            inputStream.close();
            zos.closeEntry();
            zos.close();

    }
在上面的代码中,我们使用
java.util.zip
包压缩一个文件。但我们有一个问题。也就是说,如果我们选择多个文件,那么只有一个文件被压缩。如果我们选择一个文件夹,压缩就无法工作


如何修复此问题以压缩文件、文件、文件夹、文件夹甚至嵌套文件夹?Java zip包不支持.zip、.tar、.tarGz和tarZ。因此,解决方案也不应该局限于.zip扩展名。

java的zip库不能用像压缩这个文件夹这样简单的方式来压缩文件夹

如果输入是文件夹或文件,您需要自己进行测试。如果它是一个文件-将其添加到zip。如果它是一个文件夹-迭代该文件夹并将每个文件添加到zip。对于相同的子文件夹。要向Zip添加多个文件,需要为每个文件创建ZipEntry

您可以尝试以下适用于我的代码:

public static void zip(File directory, File zipfile) throws IOException {
    URI base = directory.toURI();
    Deque<File> queue = new LinkedList<File>();
    queue.push(directory);
    OutputStream out = new FileOutputStream(zipfile);
    Closeable res = out;
    try {
        ZipOutputStream zout = new ZipOutputStream(out);
        res = zout;
        while (!queue.isEmpty()) {
            directory = queue.pop();
            for (File kid : directory.listFiles()) {
                String name = base.relativize(kid.toURI()).getPath();
                if (kid.isDirectory()) {
                    queue.push(kid);
                    name = name.endsWith("/") ? name : name + "/";
                    zout.putNextEntry(new ZipEntry(name));
                } else {
                    zout.putNextEntry(new ZipEntry(name));
                    copy(kid, zout);
                    zout.closeEntry();
                }
            }
        }
    } finally {
        res.close();
    }
}
publicstaticvoidzip(文件目录、文件zipfile)引发IOException{
URI base=directory.toURI();
Deque queue=new LinkedList();
push(目录);
OutputStream out=新文件OutputStream(zipfile);
可关闭的res=输出;
试一试{
ZipOutputStream zout=新ZipOutputStream(输出);
res=zout;
而(!queue.isEmpty()){
directory=queue.pop();
对于(文件kid:directory.listFiles()){
String name=base.relativize(kid.toURI()).getPath();
if(kid.isDirectory()){
排队。推(小孩);
name=name.endsWith(“/”)?name:name+“/”;
zout.putNextEntry(新ZipEntry(名称));
}否则{
zout.putNextEntry(新ZipEntry(名称));
复印件(孩子,佐特);
zout.closeEntry();
}
}
}
}最后{
res.close();
}
}
更新自,修复了将每个文件添加到自己目录中的问题。还可以更好地支持Windows资源管理器

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Test {

    public static void main(String agrs[]) {
        ZipUtils appZip = new ZipUtils();
        appZip.zipIt(new File(source directory), new File(dest zip));
    }

    public static class ZipUtils {

        private final List<File> fileList;

        private List<String> paths;

        public ZipUtils() {
            fileList = new ArrayList<>();
            paths = new ArrayList<>(25);
        }

        public void zipIt(File sourceFile, File zipFile) {
            if (sourceFile.isDirectory()) {
                byte[] buffer = new byte[1024];
                FileOutputStream fos = null;
                ZipOutputStream zos = null;

                try {

                    // This ensures that the zipped files are placed
                    // into a folder, within the zip file
                    // which is the same as the one been zipped
                    String sourcePath = sourceFile.getParentFile().getPath();
                    generateFileList(sourceFile);

                    fos = new FileOutputStream(zipFile);
                    zos = new ZipOutputStream(fos);

                    System.out.println("Output to Zip : " + zipFile);
                    FileInputStream in = null;

                    for (File file : this.fileList) {
                        String path = file.getParent().trim();
                        path = path.substring(sourcePath.length());

                        if (path.startsWith(File.separator)) {
                            path = path.substring(1);
                        }

                        if (path.length() > 0) {
                            if (!paths.contains(path)) {
                                paths.add(path);
                                ZipEntry ze = new ZipEntry(path + "/");
                                zos.putNextEntry(ze);
                                zos.closeEntry();
                            }
                            path += "/";
                        }

                        String entryName = path + file.getName();
                        System.out.println("File Added : " + entryName);
                        ZipEntry ze = new ZipEntry(entryName);

                        zos.putNextEntry(ze);
                        try {
                            in = new FileInputStream(file);
                            int len;
                            while ((len = in.read(buffer)) > 0) {
                                zos.write(buffer, 0, len);
                            }
                        } finally {
                            in.close();
                        }
                    }

                    zos.closeEntry();
                    System.out.println("Folder successfully compressed");

                } catch (IOException ex) {
                    ex.printStackTrace();
                } finally {
                    try {
                        zos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

        protected void generateFileList(File node) {

// add file only
            if (node.isFile()) {
                fileList.add(node);

            }

            if (node.isDirectory()) {
                File[] subNote = node.listFiles();
                for (File filename : subNote) {
                    generateFileList(filename);
                }
            }
        }
    }

}
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.zip.ZipEntry;
导入java.util.zip.ZipoutStream;
公开课考试{
公共静态void main(字符串agrs[]){
ZipUtils appZip=新的ZipUtils();
zipIt(新文件(源目录),新文件(dest-zip));
}
公共静态类ZipUtils{
私人最终清单文件清单;
私有列表路径;
公共ZipUtils(){
fileList=newarraylist();
路径=新阵列列表(25);
}
公共void zipIt(文件源文件、文件zipFile){
if(sourceFile.isDirectory()){
字节[]缓冲区=新字节[1024];
FileOutputStream=null;
ZipOutputStream zos=null;
试一试{
//这样可以确保压缩文件被放置
//放入zip文件中的文件夹中
//这和拉链上的一样
字符串sourcePath=sourceFile.getParentFile().getPath();
generateFileList(源文件);
fos=新文件输出流(zipFile);
zos=新ZipoutStream(fos);
System.out.println(“输出到Zip:+zipFile”);
FileInputStream in=null;
for(文件:this.fileList){
字符串路径=file.getParent().trim();
path=path.substring(sourcePath.length());
if(path.startsWith(File.separator)){
路径=路径子字符串(1);
}
if(path.length()>0){
如果(!path.contains(path)){
路径。添加(路径);
ZipEntry ze=新ZipEntry(路径+“/”);
佐斯·普特内森特里(泽);
zos.closeEntry();
}
路径+=“/”;
}
String entryName=path+file.getName();
System.out.println(“添加的文件:“+entryName”);
ZipEntry ze=新ZipEntry(入口名称);
佐斯·普特内森特里(泽);
试一试{
in=新文件输入流(文件);
内伦;
而((len=in.read(buffer))>0){
写入(缓冲区,0,len);
}
}最后{
in.close();
}
}
zos.closeEntry();
System.out.println(“文件夹成功压缩”);
}捕获(IOEX异常){
例如printStackTrace();
}最后{
试一试{
zos.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
}
受保护的void generateFileList(文件节点){
//仅添加文件
if(node.isFile()){
添加(节点);
}
if(node.isDirectory()){
File[]subNote=node.listFiles();
用于(文件名:subNote){
generateFileList(文件名);
}
}
}
}
}

这是我使用新java.nio包的解决方案。只需调用zipDir,给它提供目录的路径。它将在同一位置创建一个zip文件
private static Path buildPath(final Path root, final Path child) {
    if (root == null) {
        return child;
    } else {
        return Paths.get(root.toString(), child.toString());
    }
}

private static void addZipDir(final ZipOutputStream out, final Path root, final Path dir) throws IOException {
    try (DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
        for (Path child : stream) {
            Path entry = buildPath(root, child.getFileName());
            if (Files.isDirectory(child)) {
                addZipDir(out, entry, child);
            } else {
                out.putNextEntry(new ZipEntry(entry.toString()));
                Files.copy(child, out);
                out.closeEntry();
            }
        }
    }
}

public static void zipDir(final Path path) throws IOException {
    if (!Files.isDirectory(path)) {
        throw new IllegalArgumentException("Path must be a directory.");
    }

    BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(path.toString() + ".zip"));

    try (ZipOutputStream out = new ZipOutputStream(bos)) {
        addZipDir(out, path.getFileName(), path);
    }
}