php 如何逐行读取大文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13246597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to read a large file line by line?
提问by adnan masood
I want to read a file line by line, but without completely loading it in memory.
我想逐行读取文件,但没有将其完全加载到内存中。
My file is too large to open in memory, and if try to do so I always get out of memory errors.
我的文件太大而无法在内存中打开,如果尝试这样做,我总是会出现内存不足错误。
The file size is 1 GB.
文件大小为 1 GB。
回答by codaddict
You can use the fgets()function to read the file line by line:
您可以使用该fgets()函数逐行读取文件:
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
} else {
// error opening the file.
}
回答by Syuaa SE
if ($file = fopen("file.txt", "r")) {
while(!feof($file)) {
$line = fgets($file);
# do same stuff with the $line
}
fclose($file);
}
回答by elshnkhll
You can use an object oriented interface class for a file - SplFileObjecthttp://php.net/manual/en/splfileobject.fgets.php(PHP 5 >= 5.1.0)
您可以为文件使用面向对象的接口类 - 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;
回答by Nino ?kopac
If you're opening a big file, you probably want to use Generators alongside fgets() to avoid loading the whole file into memory:
如果您要打开一个大文件,您可能希望在 fgets() 旁边使用 Generators 以避免将整个文件加载到内存中:
/**
* @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);
};
Use it like this:
像这样使用它:
foreach ($fileData() as $line) {
// $line contains current line
}
This way you can process individual file lines inside the foreach().
通过这种方式,您可以在 foreach() 中处理单个文件行。
Note: Generators require >= PHP 5.5
注意:生成器需要 >= PHP 5.5
回答by NoImaginationGuy
There is a file()function that returns an array of the lines contained in the file.
有一个file()函数返回文件中包含的行的数组。
foreach(file('myfile.txt') as $line) {
echo $line. "\n";
}
回答by Starx
Use buffering techniques to read the file.
使用缓冲技术读取文件。
$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);
///
}
回答by Quolonel Questions
foreach (new SplFileObject(__FILE__) as $line) {
echo $line;
}
回答by John
The obvious answer wasn't there in all the responses.
PHP has a neat streaming delimiter parser available made for exactly that purpose.
所有的回答中都没有明显的答案。
PHP 有一个简洁的流定界符解析器,专门用于此目的。
$fp = fopen("/path/to/the/file", "r+");
while ($line = stream_get_line($fp, 1024 * 1024, "\n")) {
echo $line;
}
fclose($fp);
回答by Metodi Darzev
This how I manage with very big file (tested with up to 100G). And it's faster than fgets()
这是我如何管理非常大的文件(测试高达 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);
回答by Cuse70
Be careful with the 'while(!feof ... fgets()' stuff, fgets can get an error (returnfing false) and loop forever without reaching the end of file. codaddict was closest to being correct but when your 'while fgets' loop ends, check feof; if not true, then you had an error.
小心 'while(!feof ... fgets()' 的东西,fgets 可能会出错(返回 false)并永远循环而不会到达文件末尾。codacci 最接近正确,但是当你的 'while fgets'循环结束,检查feof;如果不是真的,那么你有一个错误。

