在 PHP 中不使用太多内存的情况下读取/写入大型 XML

Posted

技术标签:

【中文标题】在 PHP 中不使用太多内存的情况下读取/写入大型 XML【英文标题】:Read/Write large XMLs without using too much memory in PHP 【发布时间】:2018-01-06 22:35:54 【问题描述】:

我正在尝试查询一些非常大的 XML 文件(最多几个 gig),检查它们的格式是否正确,然后将它们写入硬盘。看起来很简单,但由于它们太大了,我无法在内存中保存整个文档。因此我的问题是: 当可用 RAM 小于一个文档的大小时,如何读取、检查和写入大型 XML 文件?

我的方法: 使用 XMLReader 逐个节点读取它(如果成功,则文档必须格式正确)并使用 XMLWriter 进行写入。问题:XMLWriter 似乎将所有内容都存储在 RAM 中,直到文档完成。 DOM 文档和 SimpleXML 似乎也是如此。还有什么我可以尝试的吗?

【问题讨论】:

为什么不使用XSD 来验证 XML? @halloei 能够验证文档绝对有用(而不仅仅是检查格式是否正确),但不幸的是,由于其结构经常变化,这是不可能的。 如果您使用XMLWriter::openURI(),则不会发生这种情况。它有一个内部缓冲区,因此它不会写入每个方法调用,但您可以使用XMLWriter::flush() 触发它 【参考方案1】:

您的方法似乎很合适,要解决 XMLWriter 的 RAM 问题,您可以尝试定期将内存刷新到输出文件中。

<?php
$xmlWriter = new XMLWriter();
$xmlWriter->openMemory();
$xmlWriter->startDocument('1.0', 'UTF-8');
for ($i=0; $i<=10000000; ++$i) 
    $xmlWriter->startElement('message');
    $xmlWriter->writeElement('content', 'Example content');
    $xmlWriter->endElement();
    // Flush XML in memory to file every 1000 iterations
    if (0 == $i%1000) 
        file_put_contents('example.xml', $xmlWriter->flush(true), FILE_APPEND);
    

// Final flush to make sure we haven't missed anything
file_put_contents('example.xml', $xmlWriter->flush(true), FILE_APPEND);`

来源:http://codeinthehole.com/tips/creating-large-xml-files-with-php/

【讨论】:

非常感谢,我要试试,听起来确实不错

以上是关于在 PHP 中不使用太多内存的情况下读取/写入大型 XML的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用太多内存的情况下强制下载大文件?

Google Big Query + PHP -> 如何在不耗尽内存的情况下获取大型数据集

php读取大文件如日志文件

PHP读取大文件的几种方法介绍

如何在不修改脚本的情况下计算 PHP 脚本的文件读取和写入?

php使用file函数fseek函数读取大文件效率分析