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 bufIn
và zipIn
đầ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ó).
Nguồn
2015-04-08 14:10:54
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ó? –
Đầ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
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