GZIPInputStream satır satır okuma


85

.Gz biçiminde bir dosyam var. Bu dosyayı okumak için java sınıfı GZIPInputStream'dir. Ancak, bu sınıf BufferedReader java sınıfını genişletmez. Sonuç olarak, dosyayı satır satır okuyamıyorum. Bunun gibi bir şeye ihtiyacım var

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

Java'nın Reader veya BufferedReader sınıfını genişleten ve değişkenlerinden biri olarak GZIPInputStream kullanan sınıfımı oluşturmayı düşündüm.

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

}

Ama bu kullandığım zaman çalışmıyor

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

Birisi nasıl devam edileceğini tavsiye edebilir ..


stackoverflow.com/q/6717165/779408 bağlantısına bakın . Burada bir sıkıştırma ve açma yöntemi gösterilmektedir.
Bobs

1
Bu dünyada iyi ve doğru olan her şeyin aşkı ve uzaktan bile değerli kodlar yazan tüm geliştiricilerin akıl sağlığı için ..... @erickson NOKTALARI OLARAK KODLAMANIN FARKINDA OLUN! Buna işaret eden tek cevap o, bu da ağlamak istememe neden oluyor.
James

Yanıtlar:


143

Dekoratörlerin temel düzeni şu şekildedir:

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

Bu kod parçacığındaki temel sorun, değeridir encoding. Bu, dosyadaki metnin karakter kodlamasıdır. "US-ASCII", "UTF-8", "SHIFT-JIS", "ISO-8859-9",… mi? yüzlerce olasılık vardır ve doğru seçim genellikle dosyanın kendisinden belirlenemez. Bazı bant dışı kanallar aracılığıyla belirtilmelidir.

Örneğin, belki platform varsayılanıdır. Ancak ağ bağlantılı bir ortamda bu son derece kırılgandır. Dosyayı yazan makine, komşu bölmede oturabilir, ancak farklı bir varsayılan dosya kodlamasına sahip olabilir.

Çoğu ağ protokolü, karakter kodlamasını açıkça not etmek için bir başlık veya diğer meta verileri kullanır.

Bu durumda, içeriğin XML olduğu dosya uzantısından görünür. XML, bu amaç için XML bildiriminde "kodlama" özniteliğini içerir. Ayrıca XML, metin olarak değil, bir XML ayrıştırıcıyla işlenmelidir. XML'i satır satır okumak, kırılgan, özel bir durum gibi görünüyor.

Kodlamanın açıkça belirtilmemesi ikinci emre aykırıdır. Tehlikede varsayılan kodlamayı kullanın!


1
teşekkürler işe yaradı ... Ancak, okuyucu adımına gerek yok .. GZIPInputStream gzip = new GZIPInputStream (yeni FileInputStream ("F: /gawiki-20090614-stub-meta-history.xml.gz" olarak da yazabiliriz. )); BufferedReader br = new BufferedReader (yeni InputStreamReader (gzip));
Kapil D

12
@KapilD, yorumunuzdaki ve yorumunuzdaki örnekte gösterildiği gibi kodlama hakkındaki düşüncesini tamamen kaçırmanız beni üzüyor. Ericson'ın cevabını tekrar oku .... belki 30 kat fazla.
James

Gzip komutu kodlamayı nasıl bilir? Dünyanın her yerinden bir çok linux / unix sunucusundan çok sayıda dosya okumak istiyorum ... bu yüzden bunu doğru yaptığımdan emin olmak istiyorum ... Gönderi kodlamadan bahsediyor genellikle dosyanın kendisi tarafından belirlenemez ... ancak gzip -d komutu ayrı bir girdi olmadan herhangi bir dosya üzerinde çalışıyor gibi görünüyor ... (şu anda kullandığım şey ama atlatmak istiyorum) bu yüzden gzip'in kodlamayı bilmek için ne yaptığını çözebilir miyim diye düşündüm. aynısını yapabilir. Herhangi bir düşünce / öneri beni doğru yöne yönlendirebilir mi?
glyphx

@glyphx Sorunuz net değil. İçerik türü hakkında harici bir iddia yoksa bir gzip dosyasını nasıl tanıyabileceğinizi mi söylüyorsunuz? Bir ipucu dosya uzantısı, diğeri ise dosya başlığında sihirli sayı 0x1F8B'nin varlığıdır. Ancak, her şeyi gerçekten işleyene kadar bir dosyanın geçerli bir gzip dosyası olduğunu bilemezsiniz.
erickson

1
Açık olmak gerekirse, bu dosyaların gzip dosyaları olduğunu biliyorum. Ve gzip ile sıkıştırılmış dosyaların tümü, csv ve boru sınırlama dosyaları gibi metin tabanlı dosyalardır. Sadece bu dosyaları doğrudan java ile satır satır okuyabilmek istiyorum. Onları gzip -d yapabilir ve sonra satır satır okuyabilirim. Kodlamayı belirtme zorunluluğuyla ilgili yorumlarınızda kafam karıştı ... Dosyaların çoğunun ASCII olduğunu düşünüyorum ... ama bazılarında Asya karakterleri olabilir, bu yüzden belki UTF-8? Bunu doğru yaptığımdan emin olmak istiyorum ... Bu daha anlaşılır mı? Teşekkürler!
glyphx

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


Cevabınız harika. Kısa ve öz .. Ancak, Ericson'un cevabı daha ayrıntılı.
Kapil D

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

2

Bir util sınıfında aşağıdaki yöntemi kullanabilir ve gerektiğinde kullanabilirsiniz ...

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

1

işte tek satır

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.