I tried to replace single quotes in a large XML file(110MB) with this code but an error occured. I need a code that can handle atleast 3GB XML file.
我尝试使用此代码替换大型XML文件(110MB)中的单引号但发生错误。我需要一个可以处理至少3GB XML文件的代码。
Error Message:
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20449728 bytes) in C:\xampp\htdocs\replace.php on line 10
致命错误:第10行的C:\ xampp \ htdocs \ replace.php中允许的内存大小为134217728个字节(试图分配20449728个字节)
<?php
replace_file('electronics.xml', "'", "'");
function replace_file($path, $string, $replace)
{
$file = fopen($path, 'a+');
while (feof($file) === false)
{
$str=file_get_contents($path);
$str=str_replace($string, $replace, fgets($file));
}
fclose($file);
}
echo "replace done";
?>
3 个解决方案
#1
Reading a large file into php is not recommended. Call a command line that is appropriate, like sed
不建议将大文件读入php。调用适当的命令行,如sed
Reference: http://www.grymoire.com/Unix/Sed.html
#2
Simplify:
$str = str_replace( "'","'",file_get_contents('electronics.xml'));
This is just very wrong:
这是非常错误的:
Opening XML
$file = fopen($path, 'a+');
While Loop for no reason, fgets reads to end of file, so loop completes on first iteration.
虽然Loop无缘无故,fgets读取到文件末尾,因此循环在第一次迭代时完成。
while (feof($file) === false)
{
reading in entire contents of same file file again, for no purpose
再次读取同一文件的全部内容,没有任何意义
$str=file_get_contents($path);
Reading in entire file, no length specified, so reading to EOF
读取整个文件,没有指定长度,因此读取到EOF
$str=str_replace($string, $replace, fgets($file));
}
fclose($file);
Nothing accomplished.
#3
////
//PHP 5.3 + Class find and replace string in files
//
//by Bruce Afruz
//
//2013
//
//example usage for single file:
//
//$new = new fileReplacement('./');
//$new->setExt("check.php");
//$new->changeContents("hello", "goodbye");
//
//example usage for multiple files:
//
//$new = new fileReplacement('./test');
//$new->setExt("*.html");
//$new->changeContents("hello", "goodbye");
//
//to change directory:
//
//$new = new fileReplacement('./test');
//$new->setDir("./test2");
//$new->setExt("*.html");
//$new->changeContents("hello", "goodbye");
////
class fileReplacement
{
private $ext , $dir ;
public function getDir() {
return $this->dir;
}
public function setDir($dir) {
$this->dir = $dir;
}
public function getExt() {
return $this->ext;
}
public function setExt($ext) {
$this->ext = $ext;
}
function __construct($dir) {
$this->dir = $dir;
}
public function rglob($pattern = '*', $flags = 0, $path = '') {
chdir($this->getDir());
$paths = glob($path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
$files = glob($path . $pattern, $flags);
foreach ($paths as $path) {
$files = array_merge($files, $this->rglob($pattern, $flags, $path));
}
return $files;
}
public function changeContents($replace , $sentence , $flags = 0, $path = '') {
$all = $this->rglob($this->getExt() , $flags, $path);
foreach ($all as $file) {
$filename = $file;
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
$contents = str_replace($replace , $sentence, $contents);
if (is_writable($filename)) {
if (!$handle = fopen($filename, 'w+')) {
echo "Cannot open file ($filename)
";
exit;
}
// Write $contents to our opened file.
if (fwrite($handle, $contents) === FALSE) {
echo "Cannot write to file ($filename)
";
exit;
}
echo "Success, wrote content to file ($filename)
";
fclose($handle);
} else {
echo "The file $filename is not writable
";
}
}
}}
#1
Reading a large file into php is not recommended. Call a command line that is appropriate, like sed
不建议将大文件读入php。调用适当的命令行,如sed
Reference: http://www.grymoire.com/Unix/Sed.html
#2
Simplify:
$str = str_replace( "'","'",file_get_contents('electronics.xml'));
This is just very wrong:
这是非常错误的:
Opening XML
$file = fopen($path, 'a+');
While Loop for no reason, fgets reads to end of file, so loop completes on first iteration.
虽然Loop无缘无故,fgets读取到文件末尾,因此循环在第一次迭代时完成。
while (feof($file) === false)
{
reading in entire contents of same file file again, for no purpose
再次读取同一文件的全部内容,没有任何意义
$str=file_get_contents($path);
Reading in entire file, no length specified, so reading to EOF
读取整个文件,没有指定长度,因此读取到EOF
$str=str_replace($string, $replace, fgets($file));
}
fclose($file);
Nothing accomplished.
#3
////
//PHP 5.3 + Class find and replace string in files
//
//by Bruce Afruz
//
//2013
//
//example usage for single file:
//
//$new = new fileReplacement('./');
//$new->setExt("check.php");
//$new->changeContents("hello", "goodbye");
//
//example usage for multiple files:
//
//$new = new fileReplacement('./test');
//$new->setExt("*.html");
//$new->changeContents("hello", "goodbye");
//
//to change directory:
//
//$new = new fileReplacement('./test');
//$new->setDir("./test2");
//$new->setExt("*.html");
//$new->changeContents("hello", "goodbye");
////
class fileReplacement
{
private $ext , $dir ;
public function getDir() {
return $this->dir;
}
public function setDir($dir) {
$this->dir = $dir;
}
public function getExt() {
return $this->ext;
}
public function setExt($ext) {
$this->ext = $ext;
}
function __construct($dir) {
$this->dir = $dir;
}
public function rglob($pattern = '*', $flags = 0, $path = '') {
chdir($this->getDir());
$paths = glob($path . '*', GLOB_MARK | GLOB_ONLYDIR | GLOB_NOSORT);
$files = glob($path . $pattern, $flags);
foreach ($paths as $path) {
$files = array_merge($files, $this->rglob($pattern, $flags, $path));
}
return $files;
}
public function changeContents($replace , $sentence , $flags = 0, $path = '') {
$all = $this->rglob($this->getExt() , $flags, $path);
foreach ($all as $file) {
$filename = $file;
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
$contents = str_replace($replace , $sentence, $contents);
if (is_writable($filename)) {
if (!$handle = fopen($filename, 'w+')) {
echo "Cannot open file ($filename)
";
exit;
}
// Write $contents to our opened file.
if (fwrite($handle, $contents) === FALSE) {
echo "Cannot write to file ($filename)
";
exit;
}
echo "Success, wrote content to file ($filename)
";
fclose($handle);
} else {
echo "The file $filename is not writable
";
}
}
}}