我希望逐行读取文件,但不要将其完全加载到内存中。
我的文件太大而无法在内存中打开,如果尝试这样做,我总是会出现内存错误。
文件大小为1 GB。
答案 0 :(得分:628)
您可以使用fgets()
函数逐行读取文件:
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
} else {
// error opening the file.
}
答案 1 :(得分:116)
if ($file = fopen("file.txt", "r")) {
while(!feof($file)) {
$line = fgets($file);
# do same stuff with the $line
}
fclose($file);
}
答案 2 :(得分:73)
您可以为文件使用面向对象的接口类 - SplFileObject http://php.net/manual/en/splfileobject.fgets.php(PHP 5> = 5.1.0)
<?php
$file = new SplFileObject("file.txt");
// Loop until we reach the end of the file.
while (!$file->eof()) {
// Echo one line from the file.
echo $file->fgets();
}
// Unset the file to call __destruct(), closing the file handle.
$file = null;
答案 3 :(得分:40)
如果您要打开一个大文件,您可能希望使用生成器和fgets()来避免将整个文件加载到内存中:
this.minDate = {year: 2017, month: 1, day: 1};
像这样使用:
/**
* @return Generator
*/
$fileData = function() {
$file = fopen(__DIR__ . '/file.txt', 'r');
if (!$file)
die('file does not exist or cannot be opened');
while (($line = fgets($file)) !== false) {
yield $line;
}
fclose($file);
};
这样您就可以在foreach()中处理单个文件行。
注意:生成器需要&gt; = PHP 5.5
答案 4 :(得分:28)
使用缓冲技术读取文件。
$filename = "test.txt";
$source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
while (!feof($source_file)) {
$buffer = fread($source_file, 4096); // use a buffer of 4KB
$buffer = str_replace($old,$new,$buffer);
///
}
答案 5 :(得分:26)
有一个file()
函数返回文件中包含的行数组。
foreach(file('myfile.txt') as $line) {
echo $line. "\n";
}
答案 6 :(得分:14)
foreach (new SplFileObject(__FILE__) as $line) {
echo $line;
}
答案 7 :(得分:6)
小心'while(!feof ... fgets()'的东西,fgets可以得到错误(returnfing false)并永远循环而不会到达文件末尾.codaddict最接近正确但是当你的'当fgets'循环结束时,检查feof;如果不是,那么你有一个错误。
答案 8 :(得分:5)
此问题的一个流行解决方案将出现新线字符的问题。使用简单的str_replace
可以很容易地修复它。
$handle = fopen("some_file.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$line = str_replace("\n", "", $line);
}
fclose($handle);
}
答案 9 :(得分:5)
并非所有答案中都有明显的答案。 PHP具有一个精巧的流分隔符解析器,可用于此目的。
$fp=fopen("/path/to/the/file", "r+");
while ($line = stream_get_line($fp, 1024 * 1024, "\n"))
{
echo $line;
}
fclose($fp);
答案 10 :(得分:4)
这是我如何处理非常大的文件(测试高达100G)。它比fgets()
更快$block =1024*1024;//1MB or counld be any higher than HDD block_size*2
if ($fh = fopen("file.txt", "r")) {
$left='';
while (!feof($fh)) {// read the file
$temp = fread($fh, $block);
$fgetslines = explode("\n",$temp);
$fgetslines[0]=$left.$fgetslines[0];
if(!feof($fh) )$left = array_pop($lines);
foreach ($fgetslines as $k => $line) {
//do smth with $line
}
}
}
fclose($fh);
答案 11 :(得分:2)
SplFileObject在处理大文件时非常有用。
success()
答案 12 :(得分:0)
<?php
echo '<meta charset="utf-8">';
$k= 1;
$f= 1;
$fp = fopen("texttranslate.txt", "r");
while(!feof($fp)) {
$contents = '';
for($i=1;$i<=1500;$i++){
echo $k.' -- '. fgets($fp) .'<br>';$k++;
$contents .= fgets($fp);
}
echo '<hr>';
file_put_contents('Split/new_file_'.$f.'.txt', $contents);$f++;
}
?>
答案 13 :(得分:-7)
使用数组返回读取的函数
function read_file($filename = ''){
$buffer = array();
$source_file = fopen( $filename, "r" ) or die("Couldn't open $filename");
while (!feof($source_file)) {
$buffer[] = fread($source_file, 4096); // use a buffer of 4KB
}
return $buffer;
}