2015-05-12 4 views
2

Пожалуйста, взгляните на приведенный ниже код.Как zip файлы и папки в Java?

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.

+0

Затем передать ему список файлов ... что-то вроде [это] (http://stackoverflow.com/questions/16381281/creating-folders-in-a-zip-folder-in-java/ 16381391 # 16381391) o [this] (http://stackoverflow.com/questions/28732118/java-zip-file-with-non-static-filename/28732297#28732297) например – MadProgrammer

+0

http: //www.mkyong. com/java/how-to-compress-files-in-zip-format/А также http://stackoverflow.com/questions/15968883/how-to-zip-a-folder-itself-using-java –

+0

@SercanOzdemir : Его пример отличается, мы должны определить, является ли выбранным файл или папка, а также. –

ответ

2

Библиотеки zip для java нельзя использовать для сжатия папок более простым способом - сжать эту папку.

Вам необходимо выполнить проверку, если входной файл или папка самостоятельно. Если это файл - добавьте его в 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(); 
    } 
} 
1

Обновление от this answer, который фиксирует проблему с каждого файла был добавлен в его собственном каталоге. Также лучше поддерживает Windows explorer.

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); 
       } 
      } 
     } 
    } 

} 
1

Это мое решение, которое использует новый пакет java.nio. Просто вызовите zipDir, указав ему путь к каталогу. Он создаст zip-файл в том же месте, но называется <directory>.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); 
    } 
} 
Смежные вопросы