J'essaie d'écrire une fonction qui acceptera un InputStream
avec des données de fichier zippées et retournerait un autre InputStream
avec des données décompressées.
Le fichier compressé ne contiendra qu'un seul fichier et il n'est donc pas nécessaire de créer des répertoires, etc ...
J'ai essayé de regarder ZipInputStream
et d'autres mais je suis confus par tant de types de flux différents en Java.
Concepts
GZipinputstream est destiné aux flux (ou fichiers) compressés au format gzip (extension ".gz"). Il ne contient aucune information d'en-tête.
GZipInputStream est pour [zippeddata]
Si vous avez un vrai fichier Zip, vous devez utiliser ZipFile pour ouvrir le fichier, demander la liste des fichiers (un dans votre exemple) et demander le flux d'entrée décompressé.
ZipFile est pour un fichier avec [informations d'en-tête + données zippées]
Votre méthode, si vous avez le fichier, serait quelque chose comme:
// ITS PSEUDOCODE!!
private InputStream extractOnlyFile(String path) {
ZipFile zf = new ZipFile(path);
Enumeration e = zf.entries();
ZipEntry entry = (ZipEntry) e.nextElement(); // your only file
return zf.getInputStream(entry);
}
Lecture d'un InputStream avec le contenu d'un fichier .Zip
Ok, si vous avez un InputStream, vous pouvez utiliser (comme le dit @cletus) ZipInputStream. Il lit un flux comprenant des données d'en-tête.
ZipInputStream est pour un flux avec [informations d'en-tête + données zippées]
Important: si vous avez le fichier sur votre PC, vous pouvez utiliser la classe ZipFile
pour y accéder de manière aléatoire
Voici un exemple de lecture d'un fichier Zip via un InputStream:
import Java.io.FileInputStream;
import Java.util.Zip.ZipEntry;
import Java.util.Zip.ZipInputStream;
public class Main {
public static void main(String[] args) throws Exception
{
FileInputStream fis = new FileInputStream("c:/inas400.Zip");
// this is where you start, with an InputStream containing the bytes from the Zip file
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry entry;
// while there are entries I process them
while ((entry = zis.getNextEntry()) != null)
{
System.out.println("entry: " + entry.getName() + ", " + entry.getSize());
// consume all the data from this entry
while (zis.available() > 0)
zis.read();
// I could close the entry, but getNextEntry does it automatically
// zis.closeEntry()
}
}
}
Si vous pouvez modifier les données d'entrée, je vous suggère d'utiliser GZIPInputStream
.
GZipInputStream
est différent de ZipInputStream
car vous n'avez qu'une seule donnée à l'intérieur. Ainsi, l'ensemble du flux d'entrée représente l'ensemble du fichier. Dans ZipInputStream
, le flux entier contient également la structure du ou des fichiers à l'intérieur, qui peut être multiple.
C'est sur scala syntaxe:
def unzipByteArray(input: Array[Byte]): String = {
val zipInputStream = new ZipInputStream(new ByteArrayInputStream(input))
val entry = zipInputStream.getNextEntry
IOUtils.toString(zipInputStream, StandardCharsets.UTF_8)
}
À moins que quelque chose me manque, vous devez absolument essayer de faire fonctionner ZipInputStream
et il n'y a aucune raison que cela ne le soit pas (je l'ai certainement utilisé à plusieurs reprises).
Ce que vous devez faire est d'essayer de faire fonctionner ZipInputStream
et si vous ne le pouvez pas, postez le code et nous vous aiderons avec les problèmes que vous rencontrez.
Quoi que vous fassiez, n'essayez pas de réinventer ses fonctionnalités.