2015-01-30 13 views
7

Tôi có một số mã hiện có để tạo tệp zip ở định dạng Epub 2, hoạt động chính xác.Java NIO Zip Filesystem tương đương với setMethod() trong java.util.zip.ZipEntry

Khi cố gắng cập nhật mã của mình để hỗ trợ định dạng Epub 3, tôi nghĩ mình sẽ thử Hệ thống tập tin Zip NIO Java thay vì java.util.zip.ZipFile. Tôi gần như có ngoại trừ một món đồ nhỏ.

Có một tệp 2023 mimetype bắt buộc theo định dạng Epub mà phải được đặt vào mã zip ở dạng không nén. java.util.zip.ZipEntry api cung cấp setMethod(ZipEntry.STORED) để đạt được điều này.

Tôi không thể tìm thấy bất kỳ tham chiếu nào về điều này trong tài liệu API Java NIO FileSystem. Có tương đương với ZipEntry.setMethod() không?

EDIT 1

OK, vì vậy tôi xem làm thế nào để hiển thị các thuộc tính, và cảm ơn bạn ví dụ đó, nhưng tôi không thể tìm thấy bất kỳ doc về cách tạo một thuộc tính như (zip : phương thức, 0), ngay cả trên oracle của Oracle. Các cải tiến NIO trong Java 7 dường như với tôi chỉ có khoảng 20% ​​tài liệu. Thuộc tính api doc rất thưa thớt, đặc biệt là cách tạo thuộc tính.

Cảm giác tôi bắt đầu nhận được là hệ thống tệp Zip NIO có thể không cải thiện trên java.util.zip và yêu cầu nhiều mã hơn để đạt được kết quả tương tự.

EDIT 2

tôi thử như sau:

String contents = "application/epub+zip"; /* contents of mimetype file */ 
Map<String, String> map = new HashMap<>(); 
map.put("create", "true"); 

Path zipPath = Paths.get("zipfstest.zip"); 
Files.deleteIfExists(zipPath); 

URI fileUri = zipPath.toUri(); // here 
URI zipUri = new URI("jar:" + fileUri.getScheme(), fileUri.getPath(), null); 

try (FileSystem zipfs = FileSystems.newFileSystem(zipUri, map)) { 
    Path pathInZip = zipfs.getPath("mimetype"); 
    Files.createFile(pathInZip, new ZipFileAttribute<Integer>("zip:method", 0)); 
    byte[] bytes = contents.getBytes(); 
    Files.write(pathInZip, bytes, StandardOpenOption.WRITE); 
    } 

Lớp ZipFileAttribute là một việc thực hiện tối thiểu của các thuộc tính giao diện. Tôi có thể đăng nó nhưng nó chỉ là một cặp khóa-giá trị (tên, giá trị)

Mã này tạo tệp zipFile thành công, nhưng khi tôi mở tệp zipFile với 7zip, tôi thấy tệp mimetype được lưu trữ trong mã zip là DEFLATED (8) thay vì những gì tôi cần được lưu trữ (0). Vì vậy, câu hỏi là, làm thế nào để tôi mã các thuộc tính một cách chính xác để nó lưu trữ như STORED.

Trả lời

2

Đây không phải là tài liệu rất tốt nhưng nhà cung cấp hệ thống tệp zip của JDK hỗ trợ FileAttributeView theo tên zip.

Đây là đoạn mã từ một zip của tôi:

public static void main(final String... args) 
    throws IOException 
{ 
    final Path zip = Paths.get("/home/fge/t.zip"); 
    final Map<String, ?> env = Collections.singletonMap("readonly", "true"); 
    final URI uri = URI.create("jar:" + zip.toUri()); 

    try (
     final FileSystem fs = FileSystems.newFileSystem(uri, env); 
    ) { 
     final Path slash = fs.getPath("/"); 
     Files.readAttributes(slash, "zip:*").forEach((key, val) -> { 
      System.out.println("Attribute name: " + key); 
      System.out.printf("Value: %s (class: %s)\n", val, 
       val != null ? val.getClass(): "N/A"); 
     }); 
    } 
} 

Output:

Attribute name: size 
Value: 0 (class: class java.lang.Long) 
Attribute name: creationTime 
Value: null (class: N/A) 
Attribute name: lastAccessTime 
Value: null (class: N/A) 
Attribute name: lastModifiedTime 
Value: 1969-12-31T23:59:59.999Z (class: class java.nio.file.attribute.FileTime) 
Attribute name: isDirectory 
Value: true (class: class java.lang.Boolean) 
Attribute name: isRegularFile 
Value: false (class: class java.lang.Boolean) 
Attribute name: isSymbolicLink 
Value: false (class: class java.lang.Boolean) 
Attribute name: isOther 
Value: false (class: class java.lang.Boolean) 
Attribute name: fileKey 
Value: null (class: N/A) 
Attribute name: compressedSize 
Value: 0 (class: class java.lang.Long) 
Attribute name: crc 
Value: 0 (class: class java.lang.Long) 
Attribute name: method 
Value: 0 (class: class java.lang.Integer) 

trông như "zip: Phương pháp" thuộc tính là những gì bạn muốn.

Vì vậy, nếu bạn muốn thay đổi phương pháp, nếu bạn có một Path vào hệ thống tập tin zip của bạn, có vẻ như bạn có thể làm (chưa được kiểm tra!):

Files.setAttribute(thePath, "zip:method", ZipEntry.DEFLATED); 
1

Dựa trên câu trả lời rất thú vị dưới đây, Tôi đọc lại tất cả tài liệu API sẵn có và thử các dự đoán khác nhau khi đặt thuộc tính. Tôi vẽ một cái trống trên cả hai.Tôi buộc phải rút ra kết luận rằng chức năng này là tốt nhất không có giấy tờ, và thậm chí có thể không có trong Java NIO. Vì vậy, bất kỳ ai muốn tạo tệp theo định dạng EPUB, như tôi làm, sẽ phải tiếp tục sử dụng API dựa trên ZipFile cũ. Cách khác là sử dụng mã zip vỏ được tạo bằng ZipFile hoặc một số ngôn ngữ khác, sau đó chuyển sang NIO. Cả hai tùy chọn này là - làm thế nào tôi sẽ nói - phần nào không phù hợp. Tôi nghĩ rằng nó đã được dự định cho java.io.File để trở thành bán không được chấp nhận theo thời gian.

+0

Bạn nói đúng, tôi đã có một cái nhìn tại các triển khai OpenJDK của ** ZipFileSystem.java ** và buồn bã khi viết nộp zip phương pháp này là hardcoded để "xì hơi" và không thể được ghi đè bằng "LƯU": 'u.method = METHOD_DEFLATED;' – Codetoffel

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