2009-07-03 23 views
61

J'ai un fichier au format .gz. La classe java pour lire ce fichier est GZIPInputStream. Toutefois, cette classe n'élargit pas la classe BufferedReader de Java. Par conséquent, je ne suis pas capable de lire le fichier ligne par ligne. Je besoin de quelque chose comme çaLecture GZIPInputStream ligne par ligne

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

Je pensais de créer ma classe qui étend le lecteur ou la classe 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 lorsque 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 des conseils comment procéder ..

+0

regardez sur ce lien http://stackoverflow.com/q/6717165/779408. Une méthode de compression et de décompression est représentée ici. – breceivemail

+0

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 même le code à distance utile ..... Rendez-vous compte DE CODER COMME @erickson RAPPELLE! Il est la seule réponse qui le souligne, ce qui me donne envie de pleurer. – James

Répondre

114

La configuration de base de décorateurs est comme ceci:

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

La question clé dans cet extrait est la valeur de encoding. C'est l'encodage de caractères du texte dans le fichier. Est-ce "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9", & hellip ;? il y a des centaines de possibilités, et le bon choix ne peut généralement pas être déterminé à partir du fichier lui-même. Il doit être spécifié via un canal hors bande. Par exemple, c'est peut-être la plate-forme par défaut. Dans un environnement en réseau, cependant, c'est extrêmement fragile. La machine qui a écrit le fichier pourrait s'asseoir dans la cellule 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 de caractères.

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

L'omission de spécifier explicitement l'encodage est against the second commandment.Utilisez l'encodage par défaut à vos risques et périls!

+1

grâce cela a fonctionné ... Cependant, il n'y a pas besoin de lecteur pas .. on peut aussi l'écrire comme GZIPInputStream gzip = new GZIPInputStream (new FileInputStream ("F: /gawiki-20090614-stub-meta-history.xml. gz ")); BufferReader br = new BufferedReader (nouveau InputStreamReader (gzip)); –

+12

@KapilD cela me rend triste que vous avez complètement manqué son point sur l'encodage ... comme indiqué par votre commentaire et l'exemple dans votre commentaire.Relisez la réponse d'Erickson ... peut-être 30 fois plus. – James

+0

Comment la commande gzip connaît-elle l'encodage? Je veux lire beaucoup de fichiers de beaucoup de serveurs Linux/Unix de partout dans le monde ... donc je veux m'assurer que je fais ça bien ... L'encodage post-mentions ne peut généralement pas être déterminé par le fichier lui-même ... mais la commande gzip -d semble fonctionner sur n'importe quel fichier sans entrée séparée ... (c'est ce que j'utilise maintenant mais je veux contourner) donc je me demande si je peux comprendre ce que fait gzip pour connaître l'encodage, peut faire la même chose. Des pensées/suggestions peuvent-elles me pointer dans la bonne direction? – glyphx

0

Qu'en est-:

GZIPInputStream zipReader = new GZIPInputStream(); 
InputStreamReader streamReader = new InputStreamReader(zipReader); 
BufferedReader bufferedReader = new BufferedReader(streamReader); 
34
GZIPInputStream gzip = new GZIPInputStream(new FileInputStream("F:/gawiki-20090614-stub-meta-history.xml.gz")); 
BufferedReader br = new BufferedReader(new InputStreamReader(gzip)); 
br.readLine(); 

+0

Votre réponse est géniale. Court et concis .. Cependant, la réponse d'Erickson est plus détaillée. –

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