[EDITED OP OUT這裏是短版]通過大文件循環運行的內存
通過文件循環和閱讀內容,然後寫導致函數失敗。這似乎是一個記憶問題。這是我嘗試的三個版本。
第一次嘗試這樣的:
$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++;
編輯MORE信息:
我很好奇,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++;
}
這工作。沒有失敗,內存錯誤或其他明智的。
因此,它似乎是重讀大文件的相同行的迭代的問題,或者函數的寫部分以某種方式踩在讀函數的腳趾上......老實說,沒有道理。我知道每個人都認爲它與我的陣列有關。但是我已經拿出了很多我的邏輯,我只是想讀/寫一個大文件。
'trime($ line)'是一個錯字,你的意思是'trim'或者它是你自定義的函數嗎?顯然PHP沒有'trime()'函數 –
http://stackoverflow.com/questions/2461762/force-freeing-memory-in-php –
非你的例子顯示$ arrayOfData或$ totalsToBeAdded變量來自哪裏。我懷疑當你解析這個文件時,你會不斷地加入這些變量並最終耗盡空間? –