PHP处理大文件

时间:2016-06-03 11:44:46

标签: php

我有一个1.5gig的大文件,我想做一些替换。

但是我的apache内存不足。是否有可能逐行完成这项工作?

<?php

$myfile = fopen("./m.sql", "r") or die("Unable to open file!");

$dateiinhalt = file_get_contents("./m.sql");


$search = array("ä",
    "Ä",
    "ö",
    "Ö",
    "ü",
    "Ü",
    "€",
    "§",
    "ß",
    "latin1_general_ci",
    "CHARSET=latin1",
    "‚",
    "„",
    "‘",
    "’",
    "“",
    "â€",
    "©",
    "®");

$replace = array("ä",
    "Ä",
    "ö",
    "Ö",
    "ü",
    "Ü",
    "€",
    "§",
    "ß",
    "utf8_general_ci",
    "CHARSET=utf8",
    "‚",
    "„",
    "‘",
    "’",
    "“",
    "”",
    "©",
    "®");


$content = str_replace($search, $replace, $dateiinhalt);
file_put_contents("./m.sql", $content);

echo "done";

非常感谢

更新代码:

$reading = fopen('m.sql', 'r');
$writing = fopen('m.tmp', 'w');

$replaced = false;



$search = array("ä",
    "Ä",
    "ö",
    "Ö",
    "ü",
    "Ü",
    "€",
    "§",
    "ß",
    "latin1_general_ci",
    "CHARSET=latin1",
    "‚",
    "„",
    "‘",
    "’",
    "“",
    "â€",
    "©",
    "®");

$replace = array("ä",
    "Ä",
    "ö",
    "Ö",
    "ü",
    "Ü",
    "€",
    "§",
    "ß",
    "utf8_general_ci",
    "CHARSET=utf8",
    "‚",
    "„",
    "‘",
    "’",
    "“",
    "”",
    "©",
    "®");

if ($reading) {
    // read one line or 4096 bytes, whichever comes first
    while (($dateiinhalt = fgets($reading, 4096)) !== false) {
        // replace in that and write to output file
        fwrite($writing, str_replace($search, $replace, $dateiinhalt));
    }
    if (!feof($reading)) { // fgets() failed, but not at end of file
        echo "Error: unexpected fgets() fail\n";
    }
    fclose($reading);
    fclose($writing);
}
回声“完成”;

3 个答案:

答案 0 :(得分:5)

使用fopenfgets逐行流式处理文件,而不是file_get_contents(一次将整个文件读入内存)。

答案 1 :(得分:2)

是。它并不难。您似乎已经开始了 - 在运行file_get_contents()之前不应该打开文件(除非您明确要锁定它)。

$search=Array(...
$replace=Array(...
$myfile = fopen("./m.sql", "r");
$output = fopen("./output.sql", "w");
while ($line=fgets($myfile)) {
   fputs($output, str_replace($search, $replace, $line));
} 

答案 2 :(得分:1)

事实上。要调整手册中的示例(http://php.net/manual/en/function.fgets.php):

<?php
$handleR = fopen("./m.sql", "r") or die('cannot open input file!');
$handleW = fopen("./m.out.sql", "w") or die('cannot open output file!');
if ($handleR) {
    // read one line or 4096 bytes, whichever comes first
    while (($dateiinhalt = fgets($handleR, 4096)) !== false) {
        // replace in that and write to output file
        fwrite($handleW, str_replace($search, $replace, $dateiinhalt));
    }
    if (!feof($handleR)) { // fgets() failed, but not at end of file
        echo "Error: unexpected fgets() fail\n";
    }
    fclose($handleR);
    fclose($handleW);
}