【问题标题】:How can I convert ZipInputStream to InputStream?如何将 ZipInputStream 转换为 InputStream?
【发布时间】:2011-12-12 19:54:25
【问题描述】:

我有代码,其中 ZipInputSream 转换为 byte[],但我不知道如何将其转换为输入流。

private void convertStream(String encoding, ZipInputStream in) throws IOException,
        UnsupportedEncodingException
{
    final int BUFFER = 1;
    @SuppressWarnings("unused")
    int count = 0;
    byte data[] = new byte[BUFFER];
    while ((count = in.read(data, 0, BUFFER)) != -1) 
    {
       // How can I convert data to InputStream  here ?                    
    }
}

【问题讨论】:

  • 你到底想做什么?解压缩流中的单个条目?
  • 是的,如果可能的话,我希望流中的单个文件作为 InputStream。

标签: java inputstream zipinputstream


【解决方案1】:

【讨论】:

    【解决方案2】:

    这是我解决这个问题的方法。现在我可以将 ZipInputStream 中的单个文件作为 InputStream 获取到内存中。

    private InputStream convertZipInputStreamToInputStream(ZipInputStream in, ZipEntry entry, String encoding) throws IOException
    {
        final int BUFFER = 2048;
        int count = 0;
        byte data[] = new byte[BUFFER];
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        while ((count = in.read(data, 0, BUFFER)) != -1) {
            out.write(data);
        }       
        InputStream is = new ByteArrayInputStream(out.toByteArray());
        return is;
    }
    

    【讨论】:

    • 能否请您指定使用 ZipEntry 条目、字符串编码的位置以及为什么?
    • 你应该避免这样做,它会在大文件上导致 OutOfMemoryError。相反,您可以只使用 ZipInputStream。见stackoverflow.com/questions/20020982/…
    • while ((count = in.read(buffer)) > 0) {out.write(BUFFER, 0, count);}
    • 您不需要任何这些,正如 ExtremeCoder ZipInputStream IS a InputStream 所述,或者如果您更喜欢“private InputStream convertZipInputStreamToInputStream(ZipInputStream in) { return in; }”
    • 这个特定的答案将在 out 流中添加额外的数据 out.write(data) 。正确的方法应该是out.write(data, 0, count) 当问题出现时,浪费了很多时间在我的代码中查找问题。请参阅此答案以供参考:stackoverflow.com/a/19473853/7630458.
    【解决方案3】:

    请在下面找到从 ZIP 存档中提取所有文件的函数示例。此功能不适用于子文件夹中的文件:

    private static void testZip() {
        ZipInputStream zipStream = null;
        byte buff[] = new byte[16384];
        int readBytes;
        try {
            FileInputStream fis = new FileInputStream("./test.zip");
            zipStream = new ZipInputStream(fis);
            ZipEntry ze;
            while((ze = zipStream.getNextEntry()) != null) {
                if(ze.isDirectory()) {
                    System.out.println("Folder : "+ze.getName());
                    continue;//no need to extract
                }
                System.out.println("Extracting file "+ze.getName());
                //at this moment zipStream pointing to the beginning of current ZipEntry, e.g. archived file
                //saving file
                FileOutputStream outFile = new FileOutputStream(ze.getName());
                while((readBytes = zipStream.read(buff)) != -1) {
                    outFile.write(buff, 0, readBytes);
                }
                outFile.close();                
            }
    
        } catch (Exception e) {
            System.err.println("Error processing zip file : "+e.getMessage());
        } finally {
            if(zipStream != null)
                try {
                    zipStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
        }
    }
    

    【讨论】:

    • 不是所要求的。
    【解决方案4】:

    ZipInputStream 允许直接读取 ZIP 内容:使用 getNextEntry() 进行迭代,直到找到要读取的条目,然后从 ZipInputStream 中读取。

    如果您不想只阅读 ZIP 内容,但需要在传递到下一步之前对流应用额外的转换,则可以使用 PipedInputStreamPipedOutputStream。这个想法将与此类似(凭记忆编写,甚至可能无法编译):

    import java.io.PipedInputStream;
    import java.io.PipedOutputStream;
    
    public abstract class FilterThread extends Thread {
        private InputStream unfiltered;
        public void setUnfilteredStream(InputStream unfiltered) {
            this.unfiltered = unfiltered;
        }
        private OutputStream threadOutput;
        public void setThreadOutputStream(OutputStream threadOutput) {
            this.threadOutput = threadOutput;
        }    
    
        // read from unfiltered stream, filter and write to thread output stream
        public abstract void run();
    }
    
    ...
    
    public InputStream getFilteredStream(InputStream unfiltered, FilterThread filter) {
        PipedInputStream filteredInputStream = new PipedInputStream();
        PipedOutputStream threadOutputStream = new PipedOutputStream(filteredInputStream);
    
        filter.setUnfilteredStream(unfiltered);
        filter.setThreadOuptut(threadOutputStream);
        filter.start();
    
        return filteredInputStream;
    }
    
    ...
    
    public void clientCode() {
        ...
        ZipInputStream zis = ...;// get ZIP stream
        FilterThread filter = ...; // assign your implementation of FilterThread that transforms your ZipInputStream
    
        InputStream filteredZipInputStream = getFilteredStream(zis, filter);
        ...
    }
    

    【讨论】:

      【解决方案5】:

      邮政编码相当简单,但我在将 ZipInputStream 作为 Inputstream 返回时遇到了问题。出于某种原因,zip 中包含的某些文件的字符被丢弃。以下是我的解决方案,到目前为止它一直在工作。

      private Map<String, InputStream> getFilesFromZip(final DataHandler dhZ,
              String operation) throws ServiceFault
      {
          Map<String, InputStream> fileEntries = new HashMap<String, InputStream>();
          try
          {
      
              DataSource dsZ = dhZ.getDataSource();
      
              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;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-04-12
        • 2011-02-19
        • 2013-06-11
        • 2016-04-11
        • 2020-02-27
        • 1970-01-01
        • 2021-12-05
        • 1970-01-01
        相关资源
        最近更新 更多