[ここに編集された OP は短いバージョンです]
ファイルをループして内容を読み取ってから書き込むと、関数が失敗します。メモリの問題のようでした。これは私が試した3つのバージョンです。
最初にこれを試しました:
$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++;
詳細については編集してください:
ファイルを 1 行ずつステップ実行するときに、PHP の基になるコードがイテレータに配列を使用しているかどうかに興味がありました。
また、ファイルの構築が開始されます。約 500 ~ 600k になるまで書き込んでから死ぬのを見ることができます。
最終的なファイル サイズは約 10 MB になります。
最後の更新:
これは機能します(ファイルのオープンと読み取りの欠如に注意してください):
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++;
}
更新番号 3:
私は今これをテストしました:
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++;
}
これはうまくいきました。障害、メモリエラーなどはありません。
したがって、大きなファイルの同じ行を再読み取りする反復の問題であるか、関数の書き込み部分が何らかの方法で読み取り関数のつま先を踏んでいるようです..正直に言って意味がありません. 誰もが私の配列に関係があると考えていたことを知っています。しかし、私はすべてのロジックをほとんど取り除いてしまい、大きなファイルを読み書きしようとしています。