对Freebase RDF转储的C#解析只产生1150万个N-Triples,而不是19亿个

对Freebase RDF转储的C#解析只产生1150万个N-Triples,而不是19亿个,c#,rdf,freebase,C#,Rdf,Freebase,我正在构建一个C#程序来读取数据库中的RDF数据。首先,我编写了一个简单的循环来读取文件并获得三元组的计数。然而,我的程序并没有得到文档页面(如上所述)中所述的19亿,而是只计算了1150万,然后退出。下面给出了源代码的相关部分(运行大约需要30秒) 我错过了什么 // Simple reading through the gz file try { using (FileStream fileToDecompress = File.Open(@"C:\Users\Krishna\Dow

我正在构建一个C#程序来读取数据库中的RDF数据。首先,我编写了一个简单的循环来读取文件并获得三元组的计数。然而,我的程序并没有得到文档页面(如上所述)中所述的19亿,而是只计算了1150万,然后退出。下面给出了源代码的相关部分(运行大约需要30秒)

我错过了什么

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

(我试着在
dotNetRdf
中使用
gzippendtriplesparser
通过构建来读取数据,但这似乎在一开始就遇到了
RdfParseException
(制表符分隔符?UTF-8??),因此,目前,我正在尝试使用自己的制表符).

Freebase RDF转储由一个map/reduce作业生成,该作业输出200个单独的Gzip文件。然后将这200个文件连接成一个最终的Gzip文件,将多个Gzip文件中的原始字节连接起来将生成一个有效的Gzip文件。遵守规范的库在解压缩每个输入文件时应生成一个包含连接内容的单个文件


根据您看到的三元组的数量,我猜您的代码只是解压缩文件的第一个块,而忽略了其他199个块。我不是一个很好的C#程序员,但从阅读来看,切换到C似乎可以解决这个问题。

我正在使用DotNetZip并为“gzip压缩块”解决方案创建装饰类gzip decorator

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;
    }
}
密封类gzip装饰器:流
{
私有只读流_readStream;
私有GZipStream gzip;
私人long_totalIn;
私人长途电话;
公共gzip装饰器(流readStream)
{
IfArgumentNull(readStream,“readStream”);
_readStream=readStream;
_gzip=新的GZipStream(_readStream,CompressionMode.decompresse,true);
}
公共重写整型读取(字节[]缓冲区、整型偏移量、整型计数)
{
var bytesRead=_gzip.Read(缓冲区、偏移量、计数);

if(bytesRead我通过使用“7-zip”重新打包转储文件来解决这个问题archiver。也许这对你有帮助。

如果有一个错误报告发送到dotNetRDF邮件列表或问题追踪器,解析器会被Freebase输出阻塞,那将非常感激。谢谢你指出我遗漏了什么!200个文件似乎可以解释这一点。我尝试了DotNetZip(并阅读了它们的文档)按照您的建议,但到目前为止,我还无法生成一个组合的所有文件流,我可以从中执行诸如ReadLine()之类的操作。它似乎只读取第一个文件,类似于.NET GZipStream。它显然更容易用于zip(而不是gzip)文件。我将继续进行更多的实验;如果有人可以发布任何相关的代码示例,那将非常有用!您已经解释了上面的答案如何解决解压连接的gzip文件的问题库不起作用。它们只是顺序中的第一个文件。您可以在我的答案之前阅读答案和注释,并解释有关问题m source。简单地切换到DotNetZip不起作用。我在读取gzipped nginx日志时遇到了同样的问题-只有一小部分日志被公共LIB读取。我的搜索带来了没有答案的问题。以及2002年的错误报告,并解决了“这不是一个错误”。我尝试了这个示例,但得到了“坏GZIP头”异常