2015-04-08 13 views
5

Tôi có thể xem qua ZipInputStream, nhưng trước khi bắt đầu lặp lại, tôi muốn nhận một tệp cụ thể mà tôi cần trong quá trình lặp lại. Làm thế nào tôi có thể làm điều đó?Lấy tệp cụ thể từ ZipInputStream

ZipInputStream zin = new ZipInputStream(myInputStream) 
while ((entry = zin.getNextEntry()) != null) 
{ 
    println entry.getName() 
} 
+2

Tôi không hiểu ... Lặp lại các mục cho đến khi bạn nhận được mục bạn muốn, sau đó xử lý nó? –

+1

Đầu tiên lặp lại tệp và lưu trữ nó theo cách bạn muốn. Sau đó, chỉ cần lặp lại một lần nữa. – Bubletan

+0

Cũng có ZipFile (java <7) và Zip Filesystem bắt đầu từ Java7 (mặc dù không thể từ ZipInputStream :)), đó là lý do tại sao đây không phải là câu trả lời cho câu hỏi – GPI

Trả lời

2

Nếu myInputStream bạn đang làm việc với xuất phát từ một tệp thực trên đĩa thì bạn có thể chỉ cần sử dụng java.util.zip.ZipFile thay thế, được hỗ trợ bởi một RandomAccessFile và cung cấp quyền truy cập trực tiếp vào các mục nhập theo tên. Nhưng nếu tất cả những gì bạn có là InputStream (ví dụ: nếu bạn đang xử lý luồng trực tiếp trên biên nhận từ ổ cắm mạng hoặc tương tự) thì bạn sẽ phải thực hiện bộ đệm của riêng mình.

Bạn có thể sao chép các dòng vào một tập tin tạm thời, sau đó mở tập tin đó bằng ZipFile, hoặc nếu bạn biết kích thước tối đa của dữ liệu trước (ví dụ cho một yêu cầu HTTP rằng tuyên bố Content-Length lên phía trước của nó), bạn có thể sử dụng một BufferedInputStream để đệm bộ nhớ trong bộ nhớ cho đến khi bạn tìm thấy mục nhập được yêu cầu.

BufferedInputStream bufIn = new BufferedInputStream(myInputStream); 
bufIn.mark(contentLength); 
ZipInputStream zipIn = new ZipInputStream(bufIn); 
boolean foundSpecial = false; 
while ((entry = zin.getNextEntry()) != null) { 
    if("special.txt".equals(entry.getName())) { 
    // do whatever you need with the special entry 
    foundSpecial = true; 
    break; 
    } 
} 

if(foundSpecial) { 
    // rewind 
    bufIn.reset(); 
    zipIn = new ZipInputStream(bufIn); 
    // .... 
} 

(tôi đã không kiểm tra mã này bản thân mình, bạn có thể thấy nó là cần thiết để sử dụng một cái gì đó giống như commons-io CloseShieldInputStream ở giữa bufInzipIn đầu tiên, cho phép dòng zip đầu tiên để đóng mà không đóng cửa các cơ bản bufIn trước khi bạn đã rewound nó).

+0

Đây chính là trường hợp của tôi. Cảm ơn – Jils

1

Nhìn vào Finding a file in zip entry

ZipFile file = new ZipFile("file.zip"); 
ZipInputStream zis = searchImage("foo.png", file); 

public searchImage(String name, ZipFile file) 
{ 
    for (ZipEntry e : file.entries){ 
    if (e.getName().endsWith(name)){ 
     return file.getInputStream(e); 
    } 
    } 

    return null; 
} 
+0

Phương thức 'searchImage' thiếu kiểu trả về 'ZipInputStream'. – Rooky

3

sử dụng phương thức getName() trên ZipEntry để có được những tập tin mà bạn muốn.

ZipInputStream zin = new ZipInputStream(myInputStream) 
String myFile = "foo.txt"; 
while ((entry = zin.getNextEntry()) != null) 
{ 
    if (entry.getName().equals(myFileName)) { 
     // process your file 
     // stop looking for your file - you've already found it 
     break; 
    } 
} 

Từ Java 7 trở đi, bạn nên sử dụng ZipFile thay vì ZipStream nếu bạn chỉ muốn một tập tin và bạn có một tập tin để đọc từ:

ZipFile zfile = new ZipFile(aFile); 
String myFile = "foo.txt"; 
ZipEntry entry = zfile.getEntry(myFile); 
if (entry) { 
    // process your file   
} 
+0

Đối với mã đầu tiên của bạn: hãy xem câu trả lời của tôi cho tim_yates. Đối với mã thứ hai của bạn: Tôi nghĩ có một cái gì đó tương tự như ZipFile. Vì vậy, đối với trường hợp của tôi nên sử dụng ZipFile. – Jils

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