Chcę czytać plik linia po linii, ale bez pełnego ładowania go do pamięci.
Mój plik jest zbyt duży, aby otworzyć go w pamięci, a jeśli spróbuję to zrobić, zawsze mam problemy z pamięcią.
Rozmiar pliku to 1 GB.
fgets()
bez $length
parametru.
Chcę czytać plik linia po linii, ale bez pełnego ładowania go do pamięci.
Mój plik jest zbyt duży, aby otworzyć go w pamięci, a jeśli spróbuję to zrobić, zawsze mam problemy z pamięcią.
Rozmiar pliku to 1 GB.
fgets()
bez $length
parametru.
Odpowiedzi:
Możesz użyć tej fgets()
funkcji do odczytania pliku linia po linii:
$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
części?
if ($file = fopen("file.txt", "r")) {
while(!feof($file)) {
$line = fgets($file);
# do same stuff with the $line
}
fclose($file);
}
if($file)
przed pętlą while
feof()
już nie istnieje?
Możesz użyć obiektowej klasy interfejsu dla pliku - 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()
w SplFileObject nie ma żadnej funkcji?
rtrim($file->fgets())
aby usunąć końcowe znaki nowej linii dla każdego ciągu linii, który jest czytany, jeśli nie chcesz.
Jeśli otwierasz duży plik, prawdopodobnie chcesz użyć Generatorów obok fgets (), aby uniknąć ładowania całego pliku do pamięci:
/**
* @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);
};
Użyj tego w ten sposób:
foreach ($fileData() as $line) {
// $line contains current line
}
W ten sposób możesz przetwarzać pojedyncze linie plików w foreach ().
Uwaga: Generatory wymagają> = PHP 5.5
SplFileObject
podejściem.
Użyj technik buforowania, aby odczytać plik.
$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);
///
}
Tam jest file()
funkcja, która zwraca tablicę wierszy zawartych w pliku.
foreach(file('myfile.txt') as $line) {
echo $line. "\n";
}
foreach (new SplFileObject(__FILE__) as $line) {
echo $line;
}
file()
.
Nie było oczywistej odpowiedzi we wszystkich odpowiedziach.
PHP ma schludny parser ograniczników strumieniowych dostępny specjalnie do tego celu.
$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)
Tak sobie radzę z bardzo dużym plikiem (testowanym do 100G). I jest szybszy niż 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);
Jednym z popularnych rozwiązań tego pytania będą problemy z nowym charakterem linii. Można to łatwo naprawić za pomocą prostego str_replace
.
$handle = fopen("some_file.txt", "r");
if ($handle) {
while (($line = fgets($handle)) !== false) {
$line = str_replace("\n", "", $line);
}
fclose($handle);
}
SplFileObject jest użyteczny, jeśli chodzi o obsługę dużych plików.
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++;
}
?>
Funkcja do odczytu ze znakiem powrotu tablicy
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;
}