سؤال

لدي ملف بتنسيق .gz.فئة جافا لقراءة هذا الملف هي GZIPInputStream.ومع ذلك، لا تعمل هذه الفئة على توسيع فئة BufferedReader في Java.ونتيجة لذلك، لا أستطيع قراءة الملف سطراً سطراً.انا اريد شئ ما مثل هذا

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

أفكر في إنشاء فصلي الذي يوسع فئة Reader أو BufferedReader في Java ويستخدم GZIPInputStream كأحد متغيراته.

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

}

لكن هذا لا يعمل عندما أستخدمه

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

يمكن للشخص أن ينصح كيفية المضي قدما ..

هل كانت مفيدة؟

المحلول

الإعداد الأساسي للديكور هو مثل هذا:

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

المشكلة الرئيسية في هذا المقتطف هي قيمة encoding.هذا هو ترميز الأحرف للنص الموجود في الملف.هل هو "US-ASCII"، "UTF-8"، "SHIFT-JIS"، "ISO-8859-9"، ...؟هناك المئات من الاحتمالات، وعادةً لا يمكن تحديد الاختيار الصحيح من الملف نفسه.يجب أن يتم تحديده من خلال بعض القنوات خارج النطاق.

على سبيل المثال، ربما يكون هذا هو النظام الأساسي الافتراضي.ومع ذلك، في بيئة شبكية، يكون هذا الأمر هشًا للغاية.قد يكون الجهاز الذي كتب الملف موجودًا في الحجرة المجاورة، ولكن له تشفير افتراضي مختلف للملف.

تستخدم معظم بروتوكولات الشبكة رأسًا أو بيانات تعريف أخرى لتدوين ترميز الأحرف بشكل واضح.

في هذه الحالة، يبدو من امتداد الملف أن المحتوى هو XML.يتضمن XML سمة "التشفير" في إعلان XML لهذا الغرض.علاوة على ذلك، يجب معالجة XML باستخدام محلل XML، وليس كنص.تبدو قراءة XML سطرًا بسطر بمثابة حالة خاصة هشة.

الفشل في تحديد الترميز بشكل صريح هو ضد الوصية الثانية. استخدم الترميز الافتراضي على مسؤوليتك!

نصائح أخرى

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

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

ويمكنك استخدام الطريقة التالية في فئة UTIL، واستخدامها كلما لزم الأمر ...

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

وهنا مع سطر واحد

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top