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.

Shamim Hafiz
sumber

Jawaban:

373

Bagaimana dengan File.ReadAllText:

string contents = File.ReadAllText(@"C:\temp\test.txt");
marc_s
sumber
3
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 #

Perbandingan Baca File

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 = new StreamReader(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

public static string ReadAllText(string path)
{
    if (path == null)
    {
        throw new ArgumentNullException("path");
    }
    if (path.Length == 0)
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_EmptyPath"));
    }
    return File.InternalReadAllText(path, Encoding.UTF8);
}   

private static string InternalReadAllText(string path, Encoding encoding)
{
    string result;
    using (StreamReader streamReader = new StreamReader(path, encoding))
    {
        result = streamReader.ReadToEnd();
    }
    return result;
}
Devendra D. Chavan
sumber
2
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();?
Olivier Jacot-Descombes
6

Lihatlah metode File.ReadAllText ()

Beberapa komentar penting:

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

sll
sumber
6

string text = File.ReadAllText("Path");Anda memiliki semua teks dalam satu variabel string. Jika Anda membutuhkan setiap baris secara terpisah, Anda dapat menggunakan ini:

string[] lines = File.ReadAllLines("Path");
Dilshod
sumber
4
System.IO.StreamReader myFile =
   new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();
Maxim V. Pavlov
sumber
4

@ Chris maaf. Ini kutipan MSDN Microsoft

Metodologi

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 = New StreamReader(strFileName)
Do
  line = sr.ReadLine()
Loop Until line Is Nothing
sr.Close()

FileStream (VB.NET)

Dim fs As FileStream
Dim temp As UTF8Encoding = New UTF8Encoding(True)
Dim b(1024) As Byte
fs = File.OpenRead(strFileName)
Do While fs.Read(b, 0, b.Length) > 0
    temp.GetString(b, 0, b.Length)
Loop
fs.Close()

Hasil

masukkan deskripsi gambar di sini

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.

MinhVuong
sumber
Tapi bagaimana dengan itu StreamReader.ReadToEnd?
Owen Blacker
3

nah cara tercepat artinya dengan kode C # yang paling mungkin adalah yang ini:

string readText = System.IO.File.ReadAllText(path);
Davide Piras
sumber
3

jika Anda ingin memilih file dari folder Bin aplikasi maka Anda dapat mencoba mengikuti dan jangan lupa untuk melakukan penanganan pengecualian.

string content = File.ReadAllText(Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"FilesFolder\Sample.txt"));
Deeps
sumber
3

kamu bisa memakai :

 public static void ReadFileToEnd()
{
    try
    {
    //provide to reader your complete text file
        using (StreamReader sr = new StreamReader("TestFile.txt"))
        {
            String line = sr.ReadToEnd();
            Console.WriteLine(line);
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("The file could not be read:");
        Console.WriteLine(e.Message);
    }
}
Erwin Draconis
sumber
2
string content = System.IO.File.ReadAllText( @"C:\file.txt" );
Paul Mitchell
sumber
2

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
        }
}

Melawan beberapa teknik lain , itu memenangkan sebagian besar waktu, termasuk melawan BufferedReader.


sumber
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

public static string ReadFileAndFetchStringInSingleLine(string file)
    {
        StringBuilder sb;
        try
        {
            sb = new StringBuilder();
            using (FileStream fs = File.Open(file, FileMode.Open))
            {
                using (BufferedStream bs = new BufferedStream(fs))
                {
                    using (StreamReader sr = new StreamReader(bs))
                    {
                        string str;
                        while ((str = sr.ReadLine()) != null)
                        {
                            sb.Append(str);
                        }
                    }
                }
            }
            return sb.ToString();
        }
        catch (Exception ex)
        {
            return "";
        }
    }

Semoga ini bisa membantu Anda.

Amit Kumawat
sumber
0

Anda dapat membaca teks dari file teks ke string sebagai berikut juga

string str = "";
StreamReader sr = new StreamReader(Application.StartupPath + "\\Sample.txt");
while(sr.Peek() != -1)
{
  str = str + sr.ReadLine();
}
Sai Kalyan Kumar Akshinthala
sumber
0
public partial class Testfile : System.Web.UI.Page
{
    public delegate void DelegateWriteToDB(string Inputstring);
    protected void Page_Load(object sender, EventArgs e)
    {
        getcontent(@"C:\Working\Teradata\New folder");
    }

      private void SendDataToDB(string data)
    {
        //InsertIntoData
          //Provider=SQLNCLI10.1;Integrated Security=SSPI;Persist Security Info=False;User ID="";Initial Catalog=kannan;Data Source=jaya;
        SqlConnection Conn = new SqlConnection("Data Source=aras;Initial Catalog=kannan;Integrated Security=true;");
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = Conn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "insert into test_file values('"+data+"')";
        cmd.Connection.Open();
        cmd.ExecuteNonQuery();
        cmd.Connection.Close();
    }

      private void getcontent(string path)
      {
          string[] files;
          files = Directory.GetFiles(path, "*.txt");
          StringBuilder sbData = new StringBuilder();
          StringBuilder sbErrorData = new StringBuilder();
          Testfile df = new Testfile();
          DelegateWriteToDB objDelegate = new DelegateWriteToDB(df.SendDataToDB);
          //dt.Columns.Add("Data",Type.GetType("System.String"));


          foreach (string file in files)
          {
              using (StreamReader sr = new StreamReader(file))
              {
                  String line;
                  int linelength;
                  string space = string.Empty;

                  // Read and display lines from the file until the end of 
                  // the file is reached.
                  while ((line = sr.ReadLine()) != null)
                  {
                      linelength = line.Length;
                      switch (linelength)
                      {
                          case 5:
                              space = "     ";
                              break;

                      }
                      if (linelength == 5)
                      {
                          IAsyncResult ObjAsynch = objDelegate.BeginInvoke(line + space, null, null);
                      }
                      else if (linelength == 10)
                      {
                          IAsyncResult ObjAsynch = objDelegate.BeginInvoke(line , null, null);
                      }

                  }
              }
          }
      }
    }
JAY
sumber
0

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.

Hatitye Chindove
sumber