首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何重用/重置ZipInputStream?

如何重用/重置ZipInputStream?
EN

Stack Overflow用户
提问于 2010-10-12 14:35:39
回答 5查看 7.3K关注 0票数 6

我想重置ZipInputStream (即回到开始位置),以便按顺序读取某些文件。我该怎么做?我被困住了..。

代码语言:javascript
复制
      ZipEntry entry;
        ZipInputStream input = new ZipInputStream(fileStream);//item.getInputStream());

        int check =0;
        while(check!=2){

          entry = input.getNextEntry();
          if(entry.getName().toString().equals("newFile.csv")){
              check =1;
              InputStreamReader inputStreamReader = new InputStreamReader(input);
                reader = new CSVReader(inputStreamReader);
                //read files
                //reset ZipInputStream if file is read.
                }
                reader.close();
          }
            if(entry.getName().toString().equals("anotherFile.csv")){
              check =2;
              InputStreamReader inputStreamReader = new InputStreamReader(input);
                reader = new CSVReader(inputStreamReader);
                //read files
                //reset ZipInputStream if file is read.
                }
                reader.close();
          }

        }
EN

回答 5

Stack Overflow用户

发布于 2010-10-12 14:45:53

如果可能(即您有一个实际的文件,而不仅仅是一个要读取的流),请尝试使用ZipFile类,而不是更低级的ZipInputStream。ZipFile负责在文件中跳来跳去,并向各个条目打开流。

代码语言:javascript
复制
ZipFile zip = new ZipFile(filename);
ZipEntry entry = zip.getEntry("newfile.csv");
if (entry != null){
    CSVReader data = new CSVReader(new InputStreamReader(
         zip.getInputStream(entry)));
} 
票数 5
EN

Stack Overflow用户

发布于 2017-02-10 18:44:00

实际上没有办法像你期望的那样重置一个ZipInputStream,因为它不支持重置/标记等。但是你可以使用一个ByteArrayOutputStream来缓冲你的InputStream作为byte[]

所以你写一个类,看起来像这样

代码语言:javascript
复制
private byte[] readStreamBuffer;
private InputStream readStream;

public ZipClass(InputStream readStream){
   this.readStream = readStream;
}

和一个像这样的openReadStream-method:

代码语言:javascript
复制
private ZipInputStream openReadStream(){
    if (readStreamBuffer == null) {
         //If there was no buffered data yet it will do some new
         ByteArrayOutputStream readStreamBufferStream = new ByteArrayOutputStream();
         try {
            int read = 0;
            byte[] buff = new byte[1024];
            while ((read = zipFileInput.read(buff)) != -1) {
               readStreamBufferStream.write(buff, 0, read);
            }
            readStreamBuffer = readStreamBufferStream.toByteArray();
         }
         finally {
            readStreamBufferStream.flush();
            readStreamBufferStream.close();
         }
      }
   //Read from you new buffered stream data
   readStream = new ByteArrayInputStream(readStreamBuffer);

   //open new ZipInputStream
   return new ZipInputStream(readStream);
}

现在,您可以读取条目,然后将其关闭。如果您调用openReadStream,它将为您提供一个新的ZipInputStream,因此您可以像这样选择性地读取条目:

代码语言:javascript
复制
public InputStream read(String entry){
  ZipInputStream unzipStream = openReadStream();
  try {
     return readZipEntry(unzipStream, entryName);
  }
  finally {
     unzipStream.close(); //This closes the zipinputstream
  }
}

调用方法readZipEntry

代码语言:javascript
复制
private InputStream readZipEntry(ZipInputStream zis, String entry) throws IOException {
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  try {
     // get the zipped file list entry
     try {
        ZipEntry ze = zis.getNextEntry();

        while (ze != null) {
           if (!ze.isDirectory() && ze.getName().equals(entry)) {
              int len;
              byte[] buffer = new byte[BUFFER];
              while ((len = zis.read(buffer)) > 0) {
                 out.write(buffer, 0, len);
              }
              break;
           }
           ze = zis.getNextEntry();
        }
     }
     finally {
        zis.closeEntry();
     }
     InputStream is = new ByteArrayInputStream(out.toByteArray());
     return is;
  }
  finally {
     out.close();
  }
}

你会得到一个新的InputStream。现在,您可以从同一个输入中多次读取。

票数 4
EN

Stack Overflow用户

发布于 2018-10-29 22:41:00

您可以将标记包装在BufferedInputStream中,然后调用InputStream ()和reset()方法,如下所示:

代码语言:javascript
复制
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
bufferedInputStream.mark(100);
ZipInputStream zipInputStream = new ZipInputStream(bufferedInputStream);

    any operation with zipInputStream ...

bufferedInputStream.reset();

传递给readLimit方法的标记必须足够大,以覆盖使用inputStream执行的所有读取操作。如果您将其设置为您在输入中可以拥有的最大假定文件大小,那么您应该会被覆盖。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3912172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档