2014-02-19 1 views
3

Google Freebase data dump의 RDF 데이터를 읽는 C# 프로그램을 작성하고 있습니다. 우선, 파일을 읽고 트리플의 수를 얻는 간단한 루프를 작성했습니다. 그러나 문서 페이지 (위 참조)에 명시된 19 억 건을 얻는 대신 내 프로그램은 약 1150 만 건으로 계산 한 다음 종료합니다. 소스 코드의 관련 부분이 아래에 나와 있습니다 (실행하는 데 약 30 초가 소요됩니다).Freebase RDF 덤프를 C#으로 분석하면 1 억 9000 만 개가 아닌 1150 만 개의 N 트리플이 생성됩니다.

무엇이 여기에 있습니까? ? UTF-8?). 그래서, 대한 (탭 구분 기호를

// Simple reading through the gz file 
try 
{ 
    using (FileStream fileToDecompress = File.Open(@"C:\Users\Krishna\Downloads\freebase-rdf-2014-02-16-00-00.gz", FileMode.Open)) 
    { 
     int tupleCount = 0; 
     string readLine = ""; 

     using (GZipStream decompressionStream = new GZipStream(fileToDecompress, CompressionMode.Decompress)) 
     { 
      StreamReader sr = new StreamReader(decompressionStream, detectEncodingFromByteOrderMarks: true); 

      while (true) 
      { 
       readLine = sr.ReadLine(); 
       if (readLine != null) 
       { 
        tupleCount++; 
        if (tupleCount % 1000000 == 0) 
        { Console.WriteLine(DateTime.Now.ToShortTimeString() + ": " + tupleCount.ToString()); } 
       } 
       else 
       { break; } 
      } 
      Console.WriteLine("Tuples: " + tupleCount.ToString()); 
     } 
    } 
} 
catch (Exception ex) 
{ Console.WriteLine(ex.Message); } 

는 (나는 this recommendation 구축하여 데이터를 읽을 dotNetRdfGZippedNTriplesParser를 사용했지만, 그 바로 시작 부분에 RdfParseException에 질식 할 것 같다 순간, 내 자신을 굴리려고).

+0

FreeNet 출력에서 ​​질식하는 파서가 dotNetRDF 메일 링리스트 또는 이슈 트래커에 버그 보고서를 보내면 – RobV

답변

2

Freebase RDF 덤프는 200 개의 개별 Gzip 파일을 출력하는 맵/축소 작업에 의해 작성됩니다. 그 200 개의 파일은 하나의 마지막 Gzip 파일로 연결됩니다. According to the Gzip spec, 여러 개의 Gzip 파일에서 원시 바이트를 연결하면 유효한 Gzip 파일이 생성됩니다. 명세를 준수하는 라이브러리는 해당 파일의 압축을 풀 때 각 입력 파일의 연결된 내용이있는 단일 파일을 생성해야합니다.

보고있는 트리플의 수를 기준으로, 코드가 파일의 첫 번째 청크를 압축하고 다른 199 개를 무시하는 것 같아요. 저는 C# 프로그래머가 아니지만 읽고 있습니다. another Stackoverflow answerDotNetZip으로 전환하면이 문제가 해결됩니다.

+0

Shawn이 내가 누락 된 것을 지적 해 주셔서 감사합니다! 200 개의 파일이 그것을 설명하는 것 같습니다. 귀하의 제안에 따라 DotNetZip을 실험하고 설명서를 읽었지만 지금까지는 ReadLine()과 같은 일을 할 수있는 결합 된 모든 파일 스트림을 생성 할 수 없었습니다. .NET GZipStream과 비슷한 첫 번째 파일 만 읽는 것 같습니다. 분명히 zip (gzip이 아님) 파일을 더 쉽게 허용합니다. 나는 더 많은 실험을 계속할 것이다. 누구든지 관련 코드 샘플을 게시 할 수있는 경우, 도움이 될 것입니다! –

1

저는 DotNetZip을 사용하고 "gzipped chunk"해결 방법을위한 데코레이션 클래스 GzipDecorator를 만듭니다.

sealed class GzipDecorator : Stream 
{ 
    private readonly Stream _readStream; 
    private GZipStream _gzip; 
    private long _totalIn; 
    private long _totalOut; 

    public GzipDecorator(Stream readStream) 
    { 
     Throw.IfArgumentNull(readStream, "readStream"); 
     _readStream = readStream; 
     _gzip = new GZipStream(_readStream, CompressionMode.Decompress, true); 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     var bytesRead = _gzip.Read(buffer, offset, count); 
     if (bytesRead <= 0 && _readStream.Position < _readStream.Length) 
     { 
      _totalIn += _gzip.TotalIn + 18; 
      _totalOut += _gzip.TotalOut; 
      _gzip.Dispose(); 
      _readStream.Position = _totalIn; 
      _gzip = new GZipStream(_readStream, CompressionMode.Decompress, true); 
      bytesRead = _gzip.Read(buffer, offset, count); 
     } 
     return bytesRead; 
    } 
} 
+0

위 질문에 대한 대답 주소를 설명해주십시오. –

+0

ungzip 연결 gzip 파일 용 Libs가 작동하지 않습니다. 첫 번째 파일 만 순서대로 풀립니다. 당신은 문제의 출처에 대한 설명과 함께 나의 대답 앞에서 대답과 코멘트를 읽을 수 있습니다. DotNetZip으로의 간단한 전환이 작동하지 않습니다. –

+0

gzip으로 압축 된 nginx 로그에서 읽기와 동일한 문제가 발생했습니다. 일반적인 라이브러리에서는 로그의 작은 부분 만 읽었습니다. 그리고 나의 수색은 대답없이 질문에 나를 데려 온다. 2002 년의 버그 리포트에 "이것은 버그가 아닙니다." –

0

필자는 "7-zip"아카이버를 사용하여 덤프를 다시 포장하여 문제를 해결할 수있었습니다. 어쩌면 당신을 도울 것입니다.

관련 문제