2010-10-12 4 views
4

Je souhaite réinitialiser le ZipInputStream (c'est-à-dire revenir à la position de départ) afin de lire certains fichiers dans l'ordre. Comment je fais ça? Je suis tellement stucked ...Comment réutiliser/réinitialiser un ZipInputStream?

 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(); 
      } 

     } 

Répondre

5

Si possible (à savoir que vous avez un fichier réel, pas seulement un flux de lire), essayez d'utiliser la classe ZipFile plutôt que le ZipInputStream plus bas niveau. ZipFile prend soin de sauter dans le fichier et d'ouvrir des flux vers des entrées individuelles.

ZipFile zip = new ZipFile(filename); 
ZipEntry entry = zip.getEntry("newfile.csv"); 
if (entry != null){ 
    CSVReader data = new CSVReader(new InputStreamReader(
     zip.getInputStream(entry))); 
} 
+2

'ZipInputStream' est une implémentation différente écrite en Java pur, ce n'est pas un _low-level_ de' ZipFile'. 'ZipFile' utilise JNI et ne peut pas gérer les fichiers non locaux. –

0

Essayez ceci. Il traitera chaque fichier dans le zip en utilisant un processeur csv. Dans mon système, le flux d'entrée est un flux provenant d'une connexion HTTP.

// Get the files inside the zip. 
ZipInputStream zin = new ZipInputStream(inputStream); 
ZipEntry zentry; 
while((zentry = zin.getNextEntry()) != null) { 
    String fileName = zentry.getName(); 
    long fileLength = zentry.getSize(); 
    System.out.println("fileName:: " + fileName + ", " + fileLength); 

    // csv parse it. 
    int numLines = 0; 
    CSVReader fileReader = new CSVReader(new InputStreamReader(zin)); 
    String[] nextLine; 
    while ((nextLine = fileReader.readNext()) != null) { 
     numLines++; 
    } 
    zin.closeEntry(); 

    System.out.println(" number of lines: " + numLines); 
} 
zin.close(); 
1

J'ai le même problème, je reçois InputStream de Blob et ne veulent pas d'utiliser des fichiers intermédiaires temporaires veulent ainsi remettre le ZipInputStream à relire les ZipEntries à nouveau du même objet de ZipInputStream, mais Je l'ai eu par ailleurs, ça pourrait t'aider.

ZipInputStream zis = new ZipInputStream(new BufferedInputStream(is)); 
ZipEntry ze = null; 
Map<String, byte[]> fileEntries = new HashMap<String, byte[]>(); 

while ((ze = zis.getNextEntry()) != null) { 

    ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
    byte[] buffer = new byte[1024]; 
    int count; 

    while ((count = zis.read(buffer)) != -1) { 
     baos.write(buffer, 0, count); 
    } 

    String filename = ze.getName(); 
    byte[] bytes = baos.toByteArray();      
    fileEntries.put(filename, bytes); 
} 
//do what ever with the map of fileEntries 

s'il vous plaît partager si quelqu'un a une bonne solution, grâce

+0

J'ai réfléchi à cela, mais je me préoccupe de la charge de mémoire que représente la conservation de tous les fichiers en mémoire. Quelqu'un a des pensées à ce sujet? –

0

En fait, il n'y a aucun moyen de réinitialiser un ZipInputStream comme prévu, car il ne supporte pas de remise à zéro/marqueurs etc. Mais vous peut utiliser un ByteArrayOutputStream pour tamponner votre InputStream comme byte[]

si vous écrivez une classe ressemblant à

private byte[] readStreamBuffer; 
private InputStream readStream; 

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

et un openReadStream -method comme ceci:

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); 
} 

Maintenant, vous êtes en mesure de lire une entrée et fermer ensuite. Si vous appelez openReadStream il vous fournira une nouvelle ZipInputStream, afin que vous puissiez lire sélectivement des entrées comme ceci:

public InputStream read(String entry){ 
    ZipInputStream unzipStream = openReadStream(); 
    try { 
    return readZipEntry(unzipStream, entryName); 
    } 
    finally { 
    unzipStream.close(); //This closes the zipinputstream 
    } 
} 

appelant la méthode readZipEntry

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(); 
    } 
} 

Et vous obtiendrez une nouvelle InputStream. Vous pouvez maintenant lire plusieurs fois à partir de la même entrée.

Questions connexes