2013-03-13 45 views
6

Tôi đang cố gắng nén nội dung thư mục vào lưu trữ zip bằng java. Mọi thứ đều ổn, nhưng tôi chỉ muốn làm sáng tỏ một số sự kiện. Đây là mã mà tôi sử dụng để nén tập tin:Nén tệp nén zip

public void pack(@Nonnull String archiveName, @Nonnull File outputDir, @Nonnull File targetDir) { 
    File zipFile = new File(outputDir, "out.zip"); 

    ZipOutputStream zipOutputStream = null; 
    OutputStream outputStream; 
    try { 
    // create stream for writing zip archive 
    outputStream = new FileOutputStream(zipFile); 
    zipOutputStream = new ZipOutputStream(outputStream); 
    // write files recursively 
    writeFiles(zipOutputStream, targetDir.listFiles(), ""); 
    } catch (IOException e) { 
    LOGGER.error("IO exception while packing files to archive", e); 
    } finally { 
    // close output streams 
    if (zipOutputStream != null) { 
     try { 
     zipOutputStream.close(); 
     } catch (IOException e) { 
     LOGGER.error("Unable to close zip output stream", e); 
     } 
    } 
    } 
} 

/** 
* Writes specified files and their children (in case of directories) to archive 
* 
* @param zipOutputStream archive output stream 
* @param files   which should be added to archive 
* @param path   path relative of root of archive where files should be placed 
*/ 
private void writeFiles(@Nonnull ZipOutputStream zipOutputStream, @Nullable File[] files, @Nonnull String path) throws IOException { 
    if (files == null || files.length == 0) { 
    return; 
    } 

    for (File file : files) { 
    if (file.isDirectory()) { 
     // recursively add files in this directory 
     String fullDirectoryName = path + file.getName() + "/"; 
     File[] childFiles = file.listFiles(); 
     if (childFiles != null && childFiles.length > 0) { 
     // write child files to archive. current directory will be created automatically 
     writeFiles(zipOutputStream, childFiles, fullDirectoryName); 
     } else { 
     // empty directory. write directory itself to archive 
     ZipEntry entry = new ZipEntry(fullDirectoryName); 
     zipOutputStream.putNextEntry(entry); 
     zipOutputStream.closeEntry(); 
     } 
    } else { 
     // put file in archive 
     BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(file)); 
     zipOutputStream.putNextEntry(new ZipEntry(path + file.getName())); 
     ByteStreams.copy(bufferedInputStream, zipOutputStream); 
     zipOutputStream.closeEntry(); 
     bufferedInputStream.close(); 
    } 
    } 
}

Bây giờ có những câu hỏi:

  1. Có đúng là theo mặc định (và trong trường hợp của tôi quá) Tôi sẽ nhận được đã được nén lưu trữ (sử dụng phương pháp Deflate)?

  2. Làm thế nào để có được lưu trữ không nén:

    • Nếu tôi đặt phương pháp zipOutputStream.setMethod(ZipOutputStream.STORED) tôi phải cung cấp kích thước, kích thước nén (là nó sẽ bằng với kích thước?) Và crc, nếu không tôi sẽ nhận được ngoại lệ
    • Nếu tôi không muốn tính toán kích thước và crc một mình, tôi có thể sử dụng phương pháp DEFLATE với mức 0:
      zipOutputStream.setMethod(ZipOutputStream.DEFLATED); 
      zipOutputStream.setLevel(ZipOutputStream.STORED);
      Vì vậy, có đúng là trong trường hợp này tôi không nhận được lưu trữ nén không?
    • Có phương pháp rõ ràng hơn để tạo lưu trữ không nén không?
+3

Câu trả lời này (http://stackoverflow.com/a/1207041/354831) có thể giúp bạn được lưu trữ. –

+1

Bạn cũng có thể xem xét định dạng '.tar' thay vì' .zip', cho lưu trữ không nén, tùy thuộc vào trường hợp sử dụng của bạn. Một lib cho điều đó: https://code.google.com/p/jtar/ – hyde

Trả lời

-2

Thay vì tái phát minh ra bánh xe tôi nghiêm túc muốn xem xét sử dụng một thư viện hiện cho điều này, chẳng hạn như Apache Ant. Thành ngữ cơ bản để tạo tệp zip là:

Project p = new Project(); 
p.init(); 
Zip zip = new Zip(); 
zip.setProject(p); 
zip.setDestFile(new File(outputDir, "out.zip")); 
FileSet fs = new FileSet(); 
fs.setProject(p); 
fs.setDirectory(targetDir); 
zip.addFileset(fs); 
zip.perform(); 

Theo mặc định, bạn sẽ nhận được tệp nén. Đối với một zip nén tất cả các bạn cần phải thêm là

zip.setCompress(false); 

sau setDestFile (trong thực tế bất cứ nơi nào trước khi perform).

Các vấn đề liên quan