2012-03-26 27 views
7

Tôi có một kho lưu trữ ZIP được nhúng bên trong một tệp lớn hơn. Tôi biết độ lệch bắt đầu của kho lưu trữ trong tệp lớn hơn và độ dài của nó.Đọc các tệp từ một kho lưu trữ ZIP được nhúng

Có thư viện Java nào cho phép tôi đọc trực tiếp các tệp có trong kho lưu trữ không? Tôi đang suy nghĩ dọc theo các dòng của ZipFile.getInputStream(). Thật không may, ZipFile không hoạt động cho trường hợp sử dụng này vì các nhà thầu của nó yêu cầu tệp ZIP độc lập.

Vì lý do hiệu suất, tôi không thể sao chép tệp ZIP thành tệp riêng biệt trước khi mở tệp.

chỉnh sửa: Chỉ cần rõ ràng, tôi có quyền truy cập ngẫu nhiên vào tệp.

+0

'java.util.zip.ZipInputStream.ZipInputStream (InputStream)'? – artbristol

+0

Khó. Với một tệp ZIP, trước tiên bạn cần đọc thư mục, đây là thư mục cuối cùng, vì vậy bạn cần truy cập ngẫu nhiên.Bạn * có thể * đọc tất cả các mục trong một lần từ đầu, và điều đó sẽ làm việc với hầu hết các tệp zip, nhưng định dạng chính nó cho phép những điều thú vị như mục trùng lặp và dữ liệu rác ngẫu nhiên giữa các mục nhập. – Thilo

+0

@Thilo: Chỉ cần rõ ràng, tôi có quyền truy cập ngẫu nhiên vào tệp. – NPE

Trả lời

6

Tôi đã tìm ra một bản hack nhanh (cần được vệ sinh ở đây và ở đó), nhưng nó đọc nội dung của các tệp từ kho lưu trữ ZIP được nhúng bên trong TAR. Nó sử dụng Java6, FileInputStream, ZipEntry và ZipInputStream. 'trình trên máy tính địa phương của tôi':

final FileInputStream ins = new FileInputStream("archive.tar"); 
// Zip starts at 0x1f6400, size is not needed 
long toSkip = 0x1f6400; 
// Safe skipping 
while(toSkip > 0) 
    toSkip -= ins.skip(toSkip); 

final ZipInputStream zipin = new ZipInputStream(ins); 
ZipEntry ze; 
while((ze = zipin.getNextEntry()) != null) 
{ 
    final byte[] content = new byte[(int)ze.getSize()]; 
    int offset = 0; 
    while(offset < content.length) 
    { 
     final int read = zipin.read(content, offset, content.length - offset); 
     if(read == -1) 
      break; 
     offset += read; 
    } 
    // DEBUG: print out ZIP entry name and filesize 
    System.out.println(ze + ": " + offset); 
} 
zipin.close(); 
1

1.tạo FileInputStream fis = new FileInputStream (..);

  1. đặt vị trí vào lúc bắt đầu của mã zip được nhúng: fis.skip (offset);

  2. mở ZipInputStream (FIS)

+0

sẽ hoạt động với hầu hết các tệp, nhưng định dạng tệp zip cho phép các công cụ lạ như mục trùng lặp và dữ liệu rác ngẫu nhiên giữa các mục nhập, vì vậy sẽ tốt hơn nếu bạn có quyền truy cập ngẫu nhiên và đọc thư mục ở cuối lưu trữ đầu tiên. – Thilo

-1

7-zip-JavaBinding là trình bao bọc Java cho thư viện 7-zip C++.

Trang code snippets nói riêng có một số ví dụ điển hình bao gồm in danh sách các mục trong lưu trữ, trích xuất một tệp và mở lưu trữ nhiều phần.

-1

Kiểm tra xem zip4j giúp bạn hay không.

Bạn có thể thử PartInputStream để đọc tệp zip theo trường hợp sử dụng của bạn.

Tôi nghĩ nên tạo tệp nén tạm thời và sau đó truy cập tệp đó.

1

Tôi đề xuất sử dụng TrueZIP, nó cung cấp quyền truy cập hệ thống tệp vào nhiều loại lưu trữ. Nó đã làm việc tốt cho tôi trong quá khứ.

0

Tôi nghĩ rằng nén apache commons có thể giúp bạn.

Có một lớp học org.apache.commons.compress.archivers.zip.ZipArchiveEntry, được kế thừa java.util.zip.ZipEntry.

Phương thức này có phương thức getDataOffset(), có thể bù đắp luồng dữ liệu trong tệp lưu trữ.

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