1

我有大约 2600 个大型 xml 文件(解压缩时每个 1gb),这些文件目前被压缩得相当密集,并存储在我的 SSD 上。这些文件每个包含 23000 到 30000 条记录。

我需要为每条记录保留相对少量的数据,并将这些数据保存到数据库中。

我估计(通过一些基本测试)这将需要至少 150 个小时来进行抓取(我假设持久性会很快,因为它的数据要少得多)。

我对 .NET 的 IO 方法以及如何提高它们的效率并不十分熟悉,所以这里是我目前用来测试的方法:

 public PCCompounds DoStuff(String file)
    {
        using(FileStream fs = this.LoadFile(file))
        {
            using (GZipStream gz = this.Unzip(fs))
            {
                using (XmlReader xml = this.OpenFile(gz))
                {
                    return (PCCompounds)this.ParseXMLEntity(xml);
                }
            }
        }
    }

    private FileStream LoadFile(String file)
    {
        return new FileStream(file, FileMode.Open);
    }

    private GZipStream Unzip(FileStream file)
    {
        return new GZipStream(file, CompressionMode.Decompress);
    }

    private XmlReader OpenFile(GZipStream file)
    {
        return XmlReader.Create(file);
    }

    private Object ParseXMLEntity(XmlReader xml)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(PCCompounds));

        return serializer.Deserialize(xml);
    }

不幸的是,我只在 stackoverflow 上找到了这个,而且大多数答案都有些不完整。我也读过 Sasha Goldstein 的 .NET 性能书籍,但他关于磁盘 IO 的部分有点薄。

任何建议将不胜感激。

4

1 回答 1

3

我需要为每条记录保留相对少量的数据,并将这些数据保存到数据库中。

那我建议你看看XmlReader。这个 API 非常繁琐,而且有点笨拙,你需要进行一些混乱和调试才能让它正确阅读,但它会避免很多问题;尤其是:

  • 当你知道你对子树不感兴趣时​​,你可以跳过它们
  • 你没有实例化你不需要的对象
  • ETC

当然,对于您感兴趣的位如果它不是微不足道的,您可能想要创建一个子树阅读器(其XmlReader范围限定为 parent 中的特定节点XmlReader),并将提供给XmlSerializer,以卸载复杂的努力工作XmlSerializer(所以你只需执行“下一个,下一个,下一个;决定跳过;下一个;决定通过子树反序列化”等)。

不过,最终;您将需要仔细研究所有的 IO,这需要一些时间。就个人而言,我会提出一个小标志,也许只是使用 xml 并不是前进的最佳途径。是的,这就是您现在所拥有的,但也许可以考虑启动一个项目以将未来的输出更改为开销较小的东西。

于 2013-08-19T12:54:30.397 回答