[编辑OP在这里是短篇版本]
循环浏览文件并读取内容,然后写入会导致函数失败。这似乎是一个记忆问题。这是我试过的三个版本。
首先尝试了这个:
$file = new SplFileObject($this->getDirectoryPath() . $this->getFileName(), "a+");
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
if ($this->exists()) {
foreach ($file as $line) {
$tempArray = unserialize($line);
if ($tempArray['Key'] == $arrayOfData['Key']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
}
}
$tempString = serialize($arrayOfData);
$file->fwrite("$tempString\r\n");
$this->numLines++;
然后我尝试了这个:
$file = new SplFileObject($this->getDirectoryPath() . $this->getFileName(), "a+");
$file->setFlags(SplFileObject::DROP_NEW_LINE | SplFileObject::SKIP_EMPTY);
if ($this->exists()) {
while (!$file->eof()) {
$tempArray = unserialize($file->current());
if ($tempArray['PartNumber'] == $arrayOfData['PartNumber']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
$file->next();
}
}
$tempString = serialize($arrayOfData);
$file->fwrite("$tempString\r\n");
$this->numLines++;
最后我放弃了SplFileObject,只是正常的fopen等:
$handle = fopen($this->getDirectoryPath() . $this->getFileName(), "a+");
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
$tempArray = unserialize(trim($line));
if ($tempArray['Key'] == $arrayOfData['Key']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
}
}
$tempString = serialize($arrayOfData);
fwrite($handle, "$tempString\r\n");
fclose($handle);
$this->numLines++;
编辑更多信息:
我很好奇,如果PHP的底层代码在逐行执行文件时使用了迭代器数组,这可能会导致它死掉。
此外文件确实开始构建,我可以观看它写到大约500-600k然后它就会死掉。
最终文件大小约为10mb。
最后一次更新:
这有效(注意缺少开放和阅读文件):
public function writeUnique($arrayOfData, $totalsToBeAdded) {
$tempArray = array();
$handle = fopen($this->fullPath, "a+");
$tempString = serialize($arrayOfData);
fwrite($handle, "$tempString\r\n");
fclose($handle);
$this->numLines++;
}
虽然这会中断(注意所有正在进行的操作是循环遍历整个文件然后写入文件):
public function writeUnique($arrayOfData, $totalsToBeAdded) {
$tempArray = array();
$handle = fopen($this->fullPath, "a+");
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
}
}
$tempString = serialize($arrayOfData);
fwrite($handle, "$tempString\r\n");
fclose($handle);
$this->numLines++;
}
更新号码三:
我现在测试了这个:
public function writeUnique($arrayOfData, $totalsToBeAdded) {
$handle = fopen($this->fullPath, "a+");
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
}
}
$tempString = serialize($arrayOfData);
// fwrite($handle, "$tempString\r\n"); Commented out the writing.
fclose($handle);
$this->numLines++;
}
这很有用。没有失败,记忆错误或其他明智。
所以,它似乎是重新读取大文件的相同行的迭代问题,或者函数的写入部分以某种方式踏上读取函数的脚趾..这老实说没有'有道理。我知道每个人都认为它与我的阵列有关。但是我已经完全取消了我的所有逻辑,而我只是想读/写一个大文件。
答案 0 :(得分:0)
尝试:
if ($this->exists()) {
while (false !== ($line = fgets($handle))) {
$tempArray = unserialize(trim($line));
unset($line);
if ($tempArray['Key'] == $arrayOfData['Key']) {
foreach ($totalsToBeAdded as $key) {
$arrayOfData[$key] += $tempArray[$key];
}
}
unset($tempArray);
}
}
我在这里看到的唯一持久数组是$totalsToBeAdded
和$arrayOfData
,它们看起来是+=
运算符中的一维数据,所以除了微观之外你没有什么可以做的-optimize。
答案 1 :(得分:0)
所以我终于崩溃并做了数学计算我需要php在这个文件上完成多少循环,而且这个数字是8,788,338,000,000次。
这反过来导致PHP超时。为了防止超时,需要添加这行代码。
set_time_limit(0); // ignore php timeout
现在可以逐行读取和解析临时文件。但是,对于大文件(10 mb +),到目前为止,完成该功能的时间已经超过一个小时(它仍在运行,因为我可以看到临时文件越来越大)。
我已经明白,如果速度至关重要,那么将LARGE数据集存储到临时SQL表中可能会更好。这对我来说不是一个选择,但现在我正在强制解决问题,允许它的权力。最坏的情况是senerio这至少允许它运行。
警告:这将允许无限循环永久运行并可能杀死服务器。请确认你知道如何在尝试之前通过UNIX杀死进程。