GZIPInputStream 한 줄씩 읽기


85

.gz 형식의 파일이 있습니다. 이 파일을 읽기위한 Java 클래스는 GZIPInputStream입니다. 그러나이 클래스는 java의 BufferedReader 클래스를 확장하지 않습니다. 결과적으로 파일을 한 줄씩 읽을 수 없습니다. 이런 게 필요해

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

나는 Java의 Reader 또는 BufferedReader 클래스를 확장하고 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());

진행 방법을 조언 해 줄 수있는 사람 ..


이 링크를보십시오 . stackoverflow.com/q/6717165/779408 . 압축 및 압축 해제 방법이 여기에 표시됩니다.
Bobs

1
이 세상에서 좋고 옳은 모든 것에 대한 사랑과 원격으로 가치있는 코드를 작성하는 모든 개발자의 온전함을 위해 ..... @erickson이 지적하는대로 인코딩에주의하십시오! 그는 이것을 지적하는 유일한 대답이므로 나를 울고 싶습니다.
James

답변:


143

데코레이터의 기본 설정은 다음과 같습니다.

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을 한 줄씩 읽는 것은 깨지기 쉽고 특별한 경우처럼 보입니다.

인코딩을 명시 적으로 지정하지 않는 것은 두 번째 계명에 위배됩니다. 위험에 처한 기본 인코딩을 사용하십시오!


1
감사합니다 ... 그러나 리더 단계가 필요하지 않습니다. .. GZIPInputStream gzip = new GZIPInputStream (new FileInputStream ( "F : /gawiki-20090614-stub-meta-history.xml.gz")로 작성할 수도 있습니다. )); BufferedReader br = new BufferedReader (new InputStreamReader (gzip));
Kapil D

12
@KapilD 귀하의 의견과 의견의 예에서 볼 수 있듯이 인코딩에 대한 그의 요점을 완전히 놓친 것이 슬프습니다. erickson의 대답을 다시 읽으십시오 .... 어쩌면 30 번 이상.
James

gzip 명령은 인코딩을 어떻게 알 수 있습니까? 저는 전 세계의 많은 리눅스 / 유닉스 서버에서 많은 파일을 읽고 싶습니다 ... 그래서이 작업을 올바르게 수행하고 싶습니다 ... 게시물은 일반적으로 파일 자체에 의해 인코딩을 결정할 수 없다고 언급합니다. ...하지만 gzip -d 명령은 별도의 입력없이 모든 파일에서 작동하는 것 같습니다. 똑같이 할 수 있습니다. 모든 생각 / 제안이 올바른 방향으로 나를 가리킬 수 있습니까?
glyphx

@glyphx 질문이 명확하지 않습니다. 콘텐츠 유형에 대한 외부 주장이없는 상태에서 gzip 파일을 어떻게 인식 할 수 있습니까? 하나의 힌트는 파일 확장자이고 다른 하나는 파일 헤더에 매직 넘버 0x1F8B가 있다는 것입니다. 그러나 실제로 모든 것을 처리 할 때까지 파일이 유효한 gzip 파일인지 알 수 없습니다.
erickson

1
명확히하기 위해이 파일이 gzip 파일이라는 것을 알고 있습니다. 그리고 gzipped 파일은 csv 및 pipe delim 파일과 같은 모든 텍스트 기반 파일입니다. 이 파일을 Java로 한 줄씩 직접 읽을 수 있기를 원합니다. 나는 그들을 gzip -d 할 수 있고 문제없이 한 줄씩 읽을 수 있습니다. 인코딩을 지정해야한다는 의견에 혼란 스러웠습니다. 대부분의 파일이 ASCII라고 생각합니다. 일부 파일에는 아시아 문자가있을 수 있으므로 UTF-8일까요? 이 작업을 올바르게 수행하고 있는지 확인하고 싶습니다. 더 명확합니까? 감사!
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();


당신의 대답은 훌륭합니다. 짧고 간결한 .. 그러나 erickson의 대답은 더 자세합니다.
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

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

1

여기는 한 줄입니다

try (BufferedReader br = new BufferedReader(
        new InputStreamReader(
           new GZIPInputStream(
              new FileInputStream(
                 "F:/gawiki-20090614-stub-meta-history.xml.gz"))))) 
     {br.readLine();}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.