Anda harus menggunakan fgets()tanpa $lengthparameter.
Carlos
26
Apakah Anda ingin menandai sebagai jawaban pada salah satu dari yang berikut ini?
Kim Stacks
Jawaban:
685
Anda dapat menggunakan fgets()fungsi ini untuk membaca file baris demi baris:
$handle = fopen("inputfile.txt","r");if($handle){while(($line = fgets($handle))!==false){// process the line read.}
fclose($handle);}else{// error opening the file.}
Bagaimana akun ini untuk too large to open in memorybagian itu?
Starx
64
Anda tidak membaca seluruh file dalam memori. Memori maks yang diperlukan untuk menjalankan ini tergantung pada garis terpanjang dalam input.
codaddict
13
@Brandin - Moot - Dalam situasi itu, pertanyaan yang diajukan, yaitu membaca file LINE BY LINE, tidak memiliki hasil yang jelas.
ToolmakerSteve
3
@ToolmakerSteve Kemudian tentukan apa yang harus terjadi. Jika mau, Anda bisa langsung mencetak pesan "Line terlalu lama; menyerah." dan itu adalah hasil yang didefinisikan dengan baik juga.
Brandin
2
Bisakah sebuah baris mengandung boolean false? Jika demikian maka metode ini akan berhenti tanpa mencapai akhir file. Contoh # 1 di URL ini php.net/manual/en/function.fgets.php menyarankan bahwa kadang-kadang Fool dapat mengembalikan boolean false meskipun file belum tercapai. Di bagian komentar pada halaman itu orang melaporkan bahwa fgets () tidak selalu mengembalikan nilai yang benar, jadi lebih aman menggunakan feof sebagai persyaratan loop.
cjohansson
130
if($file = fopen("file.txt","r")){while(!feof($file)){
$line = fgets($file);# do same stuff with the $line}
fclose($file);}
Seperti yang dikatakan @ Cuse70 dalam jawabannya, ini akan menyebabkan loop infinite jika file tidak ada atau tidak dapat dibuka. Tes if($file)sebelum loop sementara
FrancescoMM
10
Saya tahu ini sudah lama, tetapi: menggunakan while (! Feof ($ file)) tidak disarankan. Silahkan lihat di sini.
<?php
$file =newSplFileObject("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;
solusi yang jauh lebih bersih. terima kasih;) belum menggunakan kelas ini, ada fungsi yang lebih menarik di sini untuk dijelajahi: php.net/manual/en/class.splfileobject.php
Lukas Liesis
6
Terima kasih. Ya, misalnya Anda dapat menambahkan baris ini sebelumnya ketika $ file-> setFlags (SplFileObject :: DROP_NEW_LINE); untuk menghentikan baris baru di akhir baris.
elshnkhll
Sejauh yang saya bisa lihat tidak ada eof()fungsi di SplFileObject?
Chud37
3
Terima kasih! Juga, gunakan rtrim($file->fgets())untuk menelusur baris baru untuk setiap string baris yang dibaca jika Anda tidak menginginkannya.
Ini seharusnya menjadi jawaban yang diterima. Seratus kali lebih cepat dengan generator.
Tachi
1
Dan waaay lebih hemat memori.
Nino Škopac
2
@ NinoŠkopac: Bisakah Anda menjelaskan mengapa solusi ini lebih hemat memori? Misalnya, dibandingkan dengan SplFileObjectpendekatan.
k00ni
30
Gunakan teknik buffering untuk membaca file.
$filename ="test.txt";
$source_file = fopen( $filename,"r")ordie("Couldn't open $filename");while(!feof($source_file)){
$buffer = fread($source_file,4096);// use a buffer of 4KB
$buffer = str_replace($old,$new,$buffer);///}
ini layak mendapatkan lebih banyak cinta, karena ini akan bekerja dengan file besar, bahkan file yang tidak memiliki carriage return atau garis yang sangat panjang ...
Jimmery
Saya tidak akan terkejut jika OP tidak benar-benar peduli dengan baris aktual dan hanya ingin mis. Melayani unduhan. Dalam hal ini, jawaban ini baik-baik saja (dan apa yang sebagian besar pembuat kode PHP akan lakukan).
Álvaro González
30
Ada file()fungsi yang mengembalikan array dari baris yang ada di file.
File satu GB akan dibaca menjadi memori dan dikonversi menjadi lebih dari satu array GB ... semoga berhasil.
FrancescoMM
4
Ini bukan jawaban untuk pertanyaan yang diajukan, tetapi itu menjawab pertanyaan yang lebih umum banyak orang ketika melihat di sini, jadi itu masih berguna, terima kasih.
pilavdzice
2
file () sangat nyaman untuk bekerja dengan file kecil. Terutama ketika Anda menginginkan sebuah array () sebagai hasil akhirnya.
functionvoid
ini adalah ide yang buruk dengan file yang lebih besar karena seluruh file sedang dibaca ke array sekaligus
Flash Thunder
Ini rusak parah pada file besar, sehingga metode yang tepat tidak bekerja.
Perlu dicatat bahwa kode ini hanya akan mengembalikan baris sampai baris kosong pertama muncul. Anda perlu menguji $ line! == false dalam kondisi sementarawhile (($line = stream_get_line($fp, 1024 * 1024, "\n")) !== false)
cebe
8
Hati-hati dengan hal-hal 'while (! Feof ... fgets ()', fboards bisa mendapatkan kesalahan (returnfing false) dan loop selamanya tanpa mencapai akhir file. loop berakhir, periksa feof; jika tidak benar, maka Anda memiliki kesalahan.
Ini cara saya mengelola dengan file yang sangat besar (diuji hingga 100G). Dan ini lebih cepat dari pada fgets ()
$block =1024*1024;//1MB or counld be any higher than HDD block_size*2if($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);
bagaimana Anda memastikan bahwa blok 1024 * 1024 tidak pecah di tengah garis?
user151496
1
@ user151496 mudah !! hitung ... 1.2.3.4
Omar El Don
@ OmarElDon apa maksudmu?
Codex73
7
Salah satu solusi populer untuk pertanyaan ini akan memiliki masalah dengan karakter baris baru. Ini bisa diperbaiki dengan mudah dengan sederhana str_replace.
function read_file($filename =''){
$buffer = array();
$source_file = fopen( $filename,"r")ordie("Couldn't open $filename");while(!feof($source_file)){
$buffer[]= fread($source_file,4096);// use a buffer of 4KB}return $buffer;}
Ini akan membuat array tunggal lebih dari satu GB dalam memori (semoga sukses dengannya) dibagi bahkan tidak dalam garis tetapi dalam potongan karakter 4096 sewenang-wenang. Mengapa kamu mau melakukan itu?
fgets()
tanpa$length
parameter.Jawaban:
Anda dapat menggunakan
fgets()
fungsi ini untuk membaca file baris demi baris:sumber
too large to open in memory
bagian itu?sumber
if($file)
sebelum loop sementarafeof()
tidak ada lagi?Anda dapat menggunakan kelas antarmuka berorientasi objek untuk file - SplFileObject http://php.net/manual/en/splfileobject.fgets.php (PHP 5> = 5.1.0)
sumber
eof()
fungsi di SplFileObject?rtrim($file->fgets())
untuk menelusur baris baru untuk setiap string baris yang dibaca jika Anda tidak menginginkannya.Jika Anda membuka file besar, Anda mungkin ingin menggunakan Generator di samping fgets () untuk menghindari memuat seluruh file ke dalam memori:
Gunakan seperti ini:
Dengan cara ini Anda dapat memproses masing-masing baris file di dalam foreach ().
Catatan: Generator membutuhkan> = PHP 5.5
sumber
SplFileObject
pendekatan.Gunakan teknik buffering untuk membaca file.
sumber
Ada
file()
fungsi yang mengembalikan array dari baris yang ada di file.sumber
sumber
file()
.Jawaban yang jelas tidak ada di semua tanggapan.
PHP memiliki parser pembatas streaming yang rapi tersedia untuk tujuan itu.
sumber
while (($line = stream_get_line($fp, 1024 * 1024, "\n")) !== false)
Hati-hati dengan hal-hal 'while (! Feof ... fgets ()', fboards bisa mendapatkan kesalahan (returnfing false) dan loop selamanya tanpa mencapai akhir file. loop berakhir, periksa feof; jika tidak benar, maka Anda memiliki kesalahan.
sumber
Ini cara saya mengelola dengan file yang sangat besar (diuji hingga 100G). Dan ini lebih cepat dari pada fgets ()
sumber
Salah satu solusi populer untuk pertanyaan ini akan memiliki masalah dengan karakter baris baru. Ini bisa diperbaiki dengan mudah dengan sederhana
str_replace
.sumber
SplFileObject berguna ketika berurusan dengan file besar.
sumber
sumber
Berfungsi untuk Membaca dengan pengembalian array
sumber