ฉันต้องการอ่านไฟล์ทีละบรรทัด แต่ไม่โหลดอย่างสมบูรณ์ในหน่วยความจำ
ไฟล์ของฉันใหญ่เกินไปที่จะเปิดในหน่วยความจำและหากพยายามทำเช่นนั้นฉันจะได้รับข้อผิดพลาดจากหน่วยความจำเสมอ
ขนาดไฟล์คือ 1 GB
fgets()
โดยไม่มี$length
พารามิเตอร์
ฉันต้องการอ่านไฟล์ทีละบรรทัด แต่ไม่โหลดอย่างสมบูรณ์ในหน่วยความจำ
ไฟล์ของฉันใหญ่เกินไปที่จะเปิดในหน่วยความจำและหากพยายามทำเช่นนั้นฉันจะได้รับข้อผิดพลาดจากหน่วยความจำเสมอ
ขนาดไฟล์คือ 1 GB
fgets()
โดยไม่มี$length
พารามิเตอร์
คำตอบ:
คุณสามารถใช้fgets()
ฟังก์ชั่นเพื่ออ่านไฟล์ทีละบรรทัด:
$handle = fopen("inputfile.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
// process the line read.
}
fclose($handle);
} else {
// error opening the file.
}
too large to open in memory
ส่วนอย่างไร
if ($file = fopen("file.txt", "r")) {
while(!feof($file)) {
$line = fgets($file);
# do same stuff with the $line
}
fclose($file);
}
if($file)
ก่อนวงวนในขณะที่
feof()
ไม่มีอีกแล้วใช่ไหม
คุณสามารถใช้คลาสอินเตอร์เฟสที่มุ่งเน้นวัตถุสำหรับไฟล์ - 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;
eof()
ฟังก์ชั่นใน SplFileObject?
rtrim($file->fgets())
เพื่อตัดการขึ้นบรรทัดใหม่สำหรับแต่ละสตริงบรรทัดที่อ่านถ้าคุณไม่ต้องการ
หากคุณกำลังเปิดไฟล์ขนาดใหญ่คุณอาจต้องการใช้ Generators ควบคู่ไปกับ fgets () เพื่อหลีกเลี่ยงการโหลดไฟล์ทั้งหมดลงในหน่วยความจำ:
/**
* @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 ($fileData() as $line) {
// $line contains current line
}
วิธีนี้คุณสามารถประมวลผลแต่ละบรรทัดไฟล์ภายใน foreach ()
หมายเหตุ: เครื่องกำเนิดต้องการ> = PHP 5.5
SplFileObject
วิธีการ
ใช้เทคนิคการบัฟเฟอร์เพื่ออ่านไฟล์
$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);
///
}
มีfile()
ฟังก์ชั่นที่ส่งกลับอาร์เรย์ของบรรทัดที่มีอยู่ในไฟล์
foreach(file('myfile.txt') as $line) {
echo $line. "\n";
}
คำตอบที่ชัดเจนไม่ได้มีอยู่ในคำตอบทั้งหมด
PHP มีตัวแยกวิเคราะห์ตัวคั่นสตรีมที่เรียบร้อยซึ่งทำขึ้นเพื่อจุดประสงค์นั้น
$fp = fopen("/path/to/the/file", "r+");
while ($line = stream_get_line($fp, 1024 * 1024, "\n")) {
echo $line;
}
fclose($fp);
while (($line = stream_get_line($fp, 1024 * 1024, "\n")) !== false)
ระวังสิ่งที่ 'while (! feof ... fgets ()', fgets อาจได้รับข้อผิดพลาด (returnfing false) และวนซ้ำตลอดไปโดยไม่ถึงจุดสิ้นสุดของไฟล์ codaddict นั้นใกล้เคียงกับความถูกต้องมากที่สุด แต่เมื่อคุณ 'ในขณะที่ fgets' ลูปสิ้นสุดตรวจสอบ feof หากไม่เป็นจริงแสดงว่าคุณมีข้อผิดพลาด
นี่เป็นวิธีที่ฉันจัดการกับไฟล์ขนาดใหญ่มาก (ทดสอบด้วย 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);
หนึ่งในวิธีการแก้ปัญหายอดนิยมสำหรับคำถามนี้จะมีปัญหากับอักขระบรรทัดใหม่ str_replace
มันสามารถแก้ไขได้ง่ายด้วยสวยเรียบง่าย
$handle = fopen("some_file.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$line = str_replace("\n", "", $line);
}
fclose($handle);
}
SplFileObject มีประโยชน์เมื่อต้องจัดการกับไฟล์ขนาดใหญ่
function parse_file($filename)
{
try {
$file = new SplFileObject($filename);
} catch (LogicException $exception) {
die('SplFileObject : '.$exception->getMessage());
}
while ($file->valid()) {
$line = $file->fgets();
//do something with $line
}
//don't forget to free the file handle.
$file = null;
}
<?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++;
}
?>
ฟังก์ชั่นอ่านด้วยการส่งคืนอาเรย์
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;
}