96 votes

Lecture de GZIPInputStream ligne par ligne

J'ai un fichier au format .gz. La classe java pour lire ce fichier est GZIPInputStream. Cependant, cette classe n'étend pas la classe BufferedReader de java. Par conséquent, je ne suis pas en mesure de lire le fichier ligne par ligne. J'ai besoin de quelque chose comme ceci

reader  = new MyGZInputStream( some constructor of GZInputStream) 
reader.readLine()...

J'ai pensé créer une classe qui étend la classe Reader ou BufferedReader de java et utiliser GZIPInputStream comme une de ses variables.

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Reader;
import java.util.zip.GZIPInputStream;

public class MyGZFilReader extends Reader {

    private GZIPInputStream gzipInputStream = null;
    char[] buf = new char[1024];

    @Override
    public void close() throws IOException {
        gzipInputStream.close();
    }

    public MyGZFilReader(String filename)
               throws FileNotFoundException, IOException {
        gzipInputStream = new GZIPInputStream(new FileInputStream(filename));
    }

    @Override
    public int read(char[] cbuf, int off, int len) throws IOException {
        // TODO Auto-generated method stub
        return gzipInputStream.read((byte[])buf, off, len);
    }

}

Mais, cela ne fonctionne pas quand j'utilise

BufferedReader in = new BufferedReader(
    new MyGZFilReader("F:/gawiki-20090614-stub-meta-history.xml.gz"));
System.out.println(in.readLine());

Quelqu'un peut-il me conseiller sur la marche à suivre ?

0 votes

Regardez ce lien stackoverflow.com/q/6717165/779408 . Une méthode de compression et de décompression y est représentée.

1 votes

Pour l'amour de tout ce qui est bon et juste dans ce monde et pour la santé mentale de tous les développeurs qui écrivent du code un tant soit peu valable..... SOYEZ CONSCIENTS DE L'ENCODAGE COMME @erickson le signale ! C'est la seule réponse qui le signale, ce qui me donne envie de pleurer.

155voto

erickson Points 127945

La configuration de base des décorateurs est la suivante :

InputStream fileStream = new FileInputStream(filename);
InputStream gzipStream = new GZIPInputStream(fileStream);
Reader decoder = new InputStreamReader(gzipStream, encoding);
BufferedReader buffered = new BufferedReader(decoder);

Le point clé de cet extrait est la valeur de l'élément suivant encoding . Il s'agit du codage des caractères du texte dans le fichier. Est-ce "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9", ? il existe des centaines de possibilités, et le choix correct ne peut généralement pas être déterminé à partir du fichier lui-même. Il doit être spécifié par un canal hors bande.

Par exemple, c'est peut-être la plateforme par défaut. Dans un environnement en réseau, cependant, cela est extrêmement fragile. La machine qui a écrit le fichier peut se trouver dans la cabine voisine, mais avoir un encodage de fichier par défaut différent.

La plupart des protocoles réseau utilisent un en-tête ou d'autres métadonnées pour noter explicitement le codage des caractères.

Dans ce cas, il ressort de l'extension du fichier que le contenu est XML. XML inclut l'attribut "encoding" dans la déclaration XML à cette fin. En outre, le XML devrait vraiment être traité avec un analyseur XML, et non comme du texte. La lecture du XML ligne par ligne semble être un cas particulier et fragile.

Ne pas spécifier explicitement l'encodage est contre le deuxième commandement. Utilisez l'encodage par défaut à vos risques et périls !

1 votes

Merci cela a marché... Cependant, il n'y a pas besoin d'étape de lecture ... nous pouvons également l'écrire comme GZIPInputStream gzip = new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz")) ; BufferedReader br = new BufferedReader(new InputStreamReader(gzip)) ;

13 votes

@KapilD je suis triste de constater que vous n'avez absolument pas compris son point de vue sur l'encodage... comme le montrent votre commentaire et l'exemple dans votre commentaire. Relisez la réponse d'erickson.... peut-être 30 fois.

0 votes

Comment la commande gzip connaît-elle l'encodage ? Je veux lire beaucoup de fichiers provenant de nombreux serveurs linux/unix du monde entier... je veux donc être sûr de faire les choses correctement... Le post mentionne que l'encodage ne peut généralement pas être déterminé par le fichier lui-même... mais la commande gzip -d semble fonctionner sur tout fichier sans entrée séparée... (c'est ce que j'utilise maintenant mais que je veux contourner) donc je me dis que si je peux comprendre ce que fait gzip pour connaître l'encodage, je peux faire la même chose. Des idées/suggestions, quelqu'un peut-il m'indiquer la bonne direction ?

45voto

ChssPly76 Points 53452
GZIPInputStream gzip = new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"));
BufferedReader br = new BufferedReader(new InputStreamReader(gzip));
br.readLine();

0 votes

Votre réponse est excellente. Courte et concise Cependant, la réponse d'Erikson est plus détaillée.

4voto

Arumugam M Points 24
BufferedReader in = new BufferedReader(new InputStreamReader(
        new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz"))));

String content;

while ((content = in.readLine()) != null)

   System.out.println(content);

3voto

Memin Points 1

Vous pouvez utiliser la méthode suivante dans une classe util, et l'utiliser chaque fois que nécessaire...

public static List<String> readLinesFromGZ(String filePath) {
    List<String> lines = new ArrayList<>();
    File file = new File(filePath);

    try (GZIPInputStream gzip = new GZIPInputStream(new FileInputStream(file));
            BufferedReader br = new BufferedReader(new InputStreamReader(gzip));) {
        String line = null;
        while ((line = br.readLine()) != null) {
            lines.add(line);
        }
    } catch (FileNotFoundException e) {
        e.printStackTrace(System.err);
    } catch (IOException e) {
        e.printStackTrace(System.err);
    }
    return lines;
}

3voto

Tamer Points 65

Voici avec une ligne

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X