2010-07-13 20 views
25

Tôi nhận được một ZipInputStream từ một nguồn khác và tôi cần cung cấp InputStream của mục nhập đầu tiên cho một nguồn khác. Tôi đã hy vọng để có thể làm điều này mà không cần tiết kiệm một tập tin tạm thời trên một thiết bị, tuy nhiên cách duy nhất tôi biết nhận được một InputStream cho một mục cá nhân là thông qua ZipFile.getInputStream (mục) và kể từ khi tôi có một ZipInputStream và không phải là ZipFile, điều đó là không thể.là nó có thể nhận được đầu vào của một zipentry từ một zipinputstream?

Vì vậy, giải pháp tốt nhất tôi có là

  1. tiết kiệm InputStream đến vào một tập tin
  2. tập đọc như InputStream
  3. tập tin tạm thời xóa ZipFile
  4. sử dụng đầu tiên nhập của.

Trả lời

31

tìm:

nó hoàn toàn có thể, các cuộc gọi đến ZipInputStream.getNextEntry() vị trí InputStream vào lúc bắt đầu của sự xâm nhập và do đó cung cấp các ZipInputStream là tương đương với việc cung cấp InputStream của ZipEntry.

ZipInputStream đủ thông minh để xử lý đường xuống EOF của mục nhập hoặc có vẻ như vậy.

p.

+3

Tôi không hiểu ý bạn là gì? Bạn có thể thêm mẫu mã không? – Whitecat

+3

Điều anh ta có nghĩa là ZipInputStream có thể được sử dụng cho cả zip và đọc từng thành phần. .getNextEntry() tiến tới thành phần đầu tiên, đọc nó, làm một thành phần khác .getNextEntry() và luồng của bạn được đặt lại thành phần thứ hai và vân vân .. Thông minh, thực sự. – akauppi

11

Ngoài bài đăng @pstanton ở đây là ví dụ về mã. Tôi đã giải quyết sự cố bằng cách sử dụng mã sau. Rất khó để hiểu câu trả lời trước đó không có ví dụ.

//If you just want the first file in the zipped InputStream use this code. 
//Otherwise loop through the InputStream using getNextEntry() 
//till you find the file you want. 
private InputStream convertToInputStream(InputStream stream) throws IOException { 
    ZipInputStream zis = new ZipInputStream(stream); 
    zis.getNextEntry(); 
    return zis; 
} 

Sử dụng mã này bạn có thể trả về luồng đầu vào của tệp được nén.

+0

Và sau khi thành phần đầu tiên đã được đọc, người ta có thể '.getNextEntry()' một lần nữa, để đọc phần thứ hai. – akauppi

1

Mã zip khá dễ dàng nhưng tôi gặp sự cố khi trả về ZipInputStream dưới dạng Inputstream. Vì một số lý do, một số tệp trong zip có các ký tự bị loại bỏ. Dưới đây là giải pháp của tôi và cho đến nay nó đã được làm việc.

private Map<String, InputStream> getFilesFromZip(final DataHandler dhZ, 
     String operation) throws ServiceFault { 
    Map<String, InputStream> fileEntries = new HashMap<String, InputStream>(); 
    try { 
     ZipInputStream zipIsZ = new ZipInputStream(dhZ.getDataSource() 
     .getInputStream()); 

     try { 
      ZipEntry entry; 
      while ((entry = zipIsZ.getNextEntry()) != null) { 
       if (!entry.isDirectory()) { 
        Path p = Paths.get(entry.toString()); 
        fileEntries.put(p.getFileName().toString(), 
        convertZipInputStreamToInputStream(zipIsZ)); 
       } 
      } 
     } 
     finally { 
      zipIsZ.close(); 
     } 

    } catch (final Exception e) { 
     faultLocal(LOGGER, e, operation); 
    } 

    return fileEntries; 
} 
private InputStream convertZipInputStreamToInputStream(
final ZipInputStream in) throws IOException { 
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    IOUtils.copy(in, out); 
    InputStream is = new ByteArrayInputStream(out.toByteArray()); 
    return is; 
} 
Các vấn đề liên quan