Bagaimana cara membaca seluruh file ke string menggunakan C #?
214
Apa cara tercepat untuk membaca file teks menjadi variabel string?
Saya mengerti itu dapat dilakukan dalam beberapa cara, seperti membaca byte individu dan kemudian mengubahnya menjadi string. Saya mencari metode dengan pengkodean minimal.
Bukan fungsi terbaik untuk digunakan. Seperti yang ditunjukkan Devendra D. Chavan dalam jawabannya, StreamReader.ReadToEndlebih efisien.
Owen Blacker
40
@WenBlacker Tergantung pada apakah "tercepat" berarti "waktu yang paling singkat untuk dieksekusi" atau "waktu yang paling sedikit untuk mengerti."
bonh
2
File.ReadAllText jelas yang paling mudah digunakan, tetapi seperti yang ditunjukkan "Devendra D. Chavan, ini bukan yang tercepat. Jadi jika Anda membaca file kecil, maka itu akan menjadi pilihan yang lebih baik untuk menggunakan File.ReadAllText.it benar-benar tergantung pada seberapa besar file teks yang Anda baca.
Mana
Untuk membaca dari server periksa ini , semoga membantu seseorang.
shaijut
1
@WenBlacker - Anda yakin? Patokan menunjukkan bahwa StreamReader.ReadToEndlebih efisien daripada ReadAllLines. Yang diharapkan, karena yang terakhir juga membagi teks menjadi beberapa baris. Tetapi kita berbicara tentang metode yang berbeda ReadAllText,. Memang jawaban yang Anda sebutkan menunjukkan bahwa itu ReadAllTexthanya panggilan StreamReader.ReadToEndinternal.
Ed Avis
169
Perbandingan tolok ukur File.ReadAllLinesvs StreamReader ReadLinedari penanganan file C #
Hasil. StreamReader jauh lebih cepat untuk file besar dengan 10.000 baris, tetapi perbedaan untuk file yang lebih kecil dapat diabaikan. Seperti biasa, rencanakan untuk berbagai ukuran file, dan gunakan File.ReadAllLines hanya ketika kinerja tidak kritis.
Pendekatan StreamReader
Karena File.ReadAllTextpendekatan ini telah disarankan oleh orang lain, Anda juga dapat mencoba lebih cepat (saya belum menguji dampak kinerja secara kuantitatif, tetapi tampaknya lebih cepat daripada File.ReadAllText(lihat perbandingan di bawah)). The perbedaan dalam kinerja hanya bisa dilihat dalam kasus file yang lebih besar sekalipun.
string readContents;
using (StreamReader streamReader =newStreamReader(path,Encoding.UTF8)){
readContents = streamReader.ReadToEnd();}
Perbandingan File.Readxxx () vs StreamReader.Readxxx ()
Melihat kode indikatif melalui ILSpy Saya telah menemukan berikut tentang File.ReadAllLines, File.ReadAllText.
File.ReadAllText - Digunakan secara StreamReader.ReadToEndinternal
File.ReadAllLines - Juga menggunakan StreamReader.ReadLineinternal dengan tambahan overhead untuk menciptakan List<string>untuk kembali sebagai baris baca dan perulangan sampai akhir file.
Jadi kedua metode merupakan lapisan tambahan kenyamanan yang dibangun di atas StreamReader. Ini terbukti dengan tubuh indikatif metode ini.
File.ReadAllText() implementasi sebagaimana didekompilasi oleh ILSpy
publicstaticstringReadAllText(string path){if(path ==null){thrownewArgumentNullException("path");}if(path.Length==0){thrownewArgumentException(Environment.GetResourceString("Argument_EmptyPath"));}returnFile.InternalReadAllText(path,Encoding.UTF8);}privatestaticstringInternalReadAllText(string path,Encoding encoding){string result;
using (StreamReader streamReader =newStreamReader(path, encoding)){
result = streamReader.ReadToEnd();}return result;}
Apakah Anda membandingkan dengan File.ReadAllTextjuga ??
marc_s
2
ILSpy menyarankan itu File.ReadAllText()hanyalah penutup StreamReader.ReadToEnd(). Saya menduga bahwa lapisan tambahan harus melakukan sedikit lebih lambat daripada StreamReader.ReadToEnd().
Devendra D. Chavan
Jawaban yang bagus Mungkin sedikit banyak penjelasan bagi mereka yang hanya mencari perbaikan, tetapi setidaknya pantas sebanyak suara sebagai jawaban yang dipilih.
Sandy Gifford
@Devendra D. Chavan: Offtopic, tetapi di mana saya dapat menemukan referensi atau dokumentasi untuk ILSpy?
Viral Jain
1
Anda juga dapat menemukan kode di sini: Referenceource.microsoft.com/#mscorlib/system/io/… . Yang tidak saya dapatkan, mengapa ada perbedaan kecepatan yang signifikan jika ReadAllTexthanya untuk pembungkus streamReader.ReadToEnd();?
Metode ini membuka file, membaca setiap baris file, dan kemudian menambahkan setiap baris sebagai elemen string. Itu kemudian menutup file. Baris didefinisikan sebagai urutan karakter yang diikuti oleh carriage return ('\ r'), feed line ('\ n'), atau carriage return yang segera diikuti oleh feed baris. String yang dihasilkan tidak mengandung carriage return dan / atau umpan baris yang berakhir.
Metode ini mencoba mendeteksi pendeteksian file secara otomatis berdasarkan keberadaan tanda urutan byte. Format pengodean UTF-8 dan UTF-32 (baik big-endian dan little-endian) dapat dideteksi.
Gunakan metode ReadAllText (String, Encoding) berlebihan saat membaca file yang mungkin mengandung teks yang diimpor, karena karakter yang tidak dikenal mungkin tidak dibaca dengan benar.
Pegangan file dijamin akan ditutup dengan metode ini, meskipun ada pengecualian
string text = File.ReadAllText("Path");Anda memiliki semua teks dalam satu variabel string. Jika Anda membutuhkan setiap baris secara terpisah, Anda dapat menggunakan ini:
Dalam percobaan ini, dua kelas akan dibandingkan. Kelas StreamReaderdan FileStreamakan diarahkan untuk membaca dua file 10K dan 200K secara keseluruhan dari direktori aplikasi.
StreamReader(VB.NET)
sr =NewStreamReader(strFileName)Do
line = sr.ReadLine()LoopUntil line IsNothing
sr.Close()FileStream(VB.NET)Dim fs AsFileStreamDim temp As UTF8Encoding =New UTF8Encoding(True)Dim b(1024)AsByte
fs =File.OpenRead(strFileName)DoWhile fs.Read(b,0, b.Length)>0
temp.GetString(b,0, b.Length)Loop
fs.Close()
Hasil
FileStreamjelas lebih cepat dalam tes ini. Dibutuhkan tambahan 50% lebih banyak waktu untuk StreamReadermembaca file kecil. Untuk file besar, butuh tambahan 27% dari waktu.
StreamReadersecara khusus mencari jeda baris sementara FileStreamtidak. Ini akan mencakup beberapa waktu tambahan.
Rekomendasi
Bergantung pada apa yang perlu dilakukan aplikasi dengan bagian data, mungkin ada penguraian tambahan yang akan membutuhkan waktu pemrosesan tambahan. Pertimbangkan skenario di mana file memiliki kolom data dan baris CR/LFdibatasi. The StreamReaderakan bekerja ke bawah baris teks mencariCR/LF , dan kemudian aplikasi akan melakukan parsing tambahan mencari lokasi data tertentu. (Apakah Anda pikir String. SubString datang tanpa harga?)
Di sisi lain, FileStreammembaca data dalam potongan dan pengembang proaktif bisa menulis lebih banyak logika untuk menggunakan aliran untuk keuntungannya. Jika data yang dibutuhkan ada di posisi tertentu dalam file, ini tentu saja cara untuk pergi karena menjaga penggunaan memori turun.
FileStream adalah mekanisme yang lebih baik untuk kecepatan tetapi akan membutuhkan lebih banyak logika.
publicstaticvoidReadFileToEnd(){try{//provide to reader your complete text file
using (StreamReader sr =newStreamReader("TestFile.txt")){String line = sr.ReadToEnd();Console.WriteLine(line);}}catch(Exception e){Console.WriteLine("The file could not be read:");Console.WriteLine(e.Message);}}
Untuk pemula yang menemukan hal-hal ini menyenangkan dan menarik, cara tercepat untuk membaca seluruh file menjadi string dalam banyak kasus ( menurut tolok ukur ini ) adalah sebagai berikut:
using (StreamReader sr =File.OpenText(fileName)){string s = sr.ReadToEnd();}//you then have to process the string
Namun, yang paling cepat untuk membaca file teks secara keseluruhan adalah sebagai berikut:
using (StreamReader sr =File.OpenText(fileName)){string s =String.Empty;while((s = sr.ReadLine())!=null){//do what you have to here}}
Komentarnya terlambat, saya tahu, tetapi sedikit bingung tentang tolok ukur Anda di sini dan di halaman yang ditautkan. Tampaknya hanya menguji kecepatan baca dan tidak memuat ke seluruh string. Cuplikan kode kedua adalah membaca satu baris sekaligus dan tidak melakukan penambahan apa pun sehingga "lakukan apa yang harus Anda lakukan di sini" perlu memiliki pembuat string atau string untuk menyimpan data. Pada titik mana memori yang digunakan untuk menambah lebih banyak data akan mengubah hasil tes. Jadi s biasanya akan memiliki ukuran yang sama dengan asumsi file lebar tetap sehingga memori akan ditetapkan untuk ukuran garis dan data tidak perlu disalin ke memori baru.
Charles Byrne
2
Anda bisa menggunakan seperti ini
publicstaticstringReadFileAndFetchStringInSingleLine(string file){StringBuilder sb;try{
sb =newStringBuilder();
using (FileStream fs =File.Open(file,FileMode.Open)){
using (BufferedStream bs =newBufferedStream(fs)){
using (StreamReader sr =newStreamReader(bs)){string str;while((str = sr.ReadLine())!=null){
sb.Append(str);}}}}return sb.ToString();}catch(Exception ex){return"";}}
Saya membuat perbandingan antara ReadAllText dan StreamBuffer untuk csv 2Mb dan tampaknya perbedaannya cukup kecil tetapi ReadAllText tampaknya mengambil alih posisi dari waktu yang dibutuhkan untuk menyelesaikan fungsi.
Jawaban:
Bagaimana dengan
File.ReadAllText
:sumber
StreamReader.ReadToEnd
lebih efisien.StreamReader.ReadToEnd
lebih efisien daripadaReadAllLines
. Yang diharapkan, karena yang terakhir juga membagi teks menjadi beberapa baris. Tetapi kita berbicara tentang metode yang berbedaReadAllText
,. Memang jawaban yang Anda sebutkan menunjukkan bahwa ituReadAllText
hanya panggilanStreamReader.ReadToEnd
internal.Perbandingan tolok ukur
File.ReadAllLines
vsStreamReader ReadLine
dari penanganan file C #Pendekatan StreamReader
Karena
File.ReadAllText
pendekatan ini telah disarankan oleh orang lain, Anda juga dapat mencoba lebih cepat (saya belum menguji dampak kinerja secara kuantitatif, tetapi tampaknya lebih cepat daripadaFile.ReadAllText
(lihat perbandingan di bawah)). The perbedaan dalam kinerja hanya bisa dilihat dalam kasus file yang lebih besar sekalipun.Perbandingan File.Readxxx () vs StreamReader.Readxxx ()
Melihat kode indikatif melalui ILSpy Saya telah menemukan berikut tentang
File.ReadAllLines
,File.ReadAllText
.File.ReadAllText
- Digunakan secaraStreamReader.ReadToEnd
internalFile.ReadAllLines
- Juga menggunakanStreamReader.ReadLine
internal dengan tambahan overhead untuk menciptakanList<string>
untuk kembali sebagai baris baca dan perulangan sampai akhir file.Jadi kedua metode merupakan lapisan tambahan kenyamanan yang dibangun di atas
StreamReader
. Ini terbukti dengan tubuh indikatif metode ini.File.ReadAllText()
implementasi sebagaimana didekompilasi oleh ILSpysumber
File.ReadAllText
juga ??File.ReadAllText()
hanyalah penutupStreamReader.ReadToEnd()
. Saya menduga bahwa lapisan tambahan harus melakukan sedikit lebih lambat daripadaStreamReader.ReadToEnd()
.ReadAllText
hanya untuk pembungkusstreamReader.ReadToEnd();
?Berikut dokumentasi MSDN
sumber
Lihatlah metode File.ReadAllText ()
Beberapa komentar penting:
sumber
string text = File.ReadAllText("Path");
Anda memiliki semua teks dalam satu variabel string. Jika Anda membutuhkan setiap baris secara terpisah, Anda dapat menggunakan ini:sumber
sumber
@ Chris maaf. Ini kutipan
MSDN Microsoft
Metodologi
Dalam percobaan ini, dua kelas akan dibandingkan. Kelas
StreamReader
danFileStream
akan diarahkan untuk membaca dua file 10K dan 200K secara keseluruhan dari direktori aplikasi.Hasil
FileStream
jelas lebih cepat dalam tes ini. Dibutuhkan tambahan 50% lebih banyak waktu untukStreamReader
membaca file kecil. Untuk file besar, butuh tambahan 27% dari waktu.StreamReader
secara khusus mencari jeda baris sementaraFileStream
tidak. Ini akan mencakup beberapa waktu tambahan.Rekomendasi
Bergantung pada apa yang perlu dilakukan aplikasi dengan bagian data, mungkin ada penguraian tambahan yang akan membutuhkan waktu pemrosesan tambahan. Pertimbangkan skenario di mana file memiliki kolom data dan baris
CR/LF
dibatasi. TheStreamReader
akan bekerja ke bawah baris teks mencariCR/LF
, dan kemudian aplikasi akan melakukan parsing tambahan mencari lokasi data tertentu. (Apakah Anda pikir String. SubString datang tanpa harga?)Di sisi lain,
FileStream
membaca data dalam potongan dan pengembang proaktif bisa menulis lebih banyak logika untuk menggunakan aliran untuk keuntungannya. Jika data yang dibutuhkan ada di posisi tertentu dalam file, ini tentu saja cara untuk pergi karena menjaga penggunaan memori turun.FileStream
adalah mekanisme yang lebih baik untuk kecepatan tetapi akan membutuhkan lebih banyak logika.sumber
StreamReader.ReadToEnd
?nah cara tercepat artinya dengan kode C # yang paling mungkin adalah yang ini:
sumber
jika Anda ingin memilih file dari folder Bin aplikasi maka Anda dapat mencoba mengikuti dan jangan lupa untuk melakukan penanganan pengecualian.
sumber
kamu bisa memakai :
sumber
sumber
Untuk pemula yang menemukan hal-hal ini menyenangkan dan menarik, cara tercepat untuk membaca seluruh file menjadi string dalam banyak kasus ( menurut tolok ukur ini ) adalah sebagai berikut:
Namun, yang paling cepat untuk membaca file teks secara keseluruhan adalah sebagai berikut:
Melawan beberapa teknik lain , itu memenangkan sebagian besar waktu, termasuk melawan BufferedReader.
sumber
Anda bisa menggunakan seperti ini
Semoga ini bisa membantu Anda.
sumber
Anda dapat membaca teks dari file teks ke string sebagai berikut juga
sumber
sumber
Saya membuat perbandingan antara ReadAllText dan StreamBuffer untuk csv 2Mb dan tampaknya perbedaannya cukup kecil tetapi ReadAllText tampaknya mengambil alih posisi dari waktu yang dibutuhkan untuk menyelesaikan fungsi.
sumber