Làm cách nào để đọc toàn bộ tệp vào một chuỗi bằng C #?


214

Cách nhanh nhất để đọc tệp văn bản thành một biến chuỗi là gì?

Tôi hiểu nó có thể được thực hiện theo nhiều cách, chẳng hạn như đọc từng byte riêng lẻ và sau đó chuyển đổi chúng thành chuỗi. Tôi đã tìm kiếm một phương pháp với mã hóa tối thiểu.


Câu trả lời:


373

Thế còn File.ReadAllText:

string contents = File.ReadAllText(@"C:\temp\test.txt");

3
Không phải là chức năng tốt nhất để sử dụng, mặc dù. Như Devendra D. Chavan chỉ ra trong câu trả lời của mình, StreamReader.ReadToEndsẽ hiệu quả hơn.
Owen Blacker

40
@OwenBlacker Nó phụ thuộc vào việc "nhanh nhất" có nghĩa là "ít thời gian nhất để thực hiện" hay "ít thời gian nhất để hiểu".
bonh

2
File.ReadAllText chắc chắn là ứng dụng dễ sử dụng nhất, nhưng như "Devendra D. Chavan" chỉ ra, nó không phải là nhanh nhất. Vì vậy, nếu bạn đang đọc các tệp nhỏ, thì nó sẽ là một lựa chọn tốt hơn để sử dụng File.ReadAllText.it thực sự phụ thuộc vào mức độ lớn của các tệp văn bản mà bạn đang đọc.
Mana

Để đọc từ máy chủ kiểm tra điều này , hy vọng sẽ giúp được ai đó.
shaijut

1
@OwenBlacker - bạn có chắc không? Các tiêu chuẩn cho thấy rằng StreamReader.ReadToEndhiệu quả hơn ReadAllLines. Đó là dự kiến, vì sau này cũng chia văn bản thành các dòng. Nhưng chúng ta đang nói về một phương pháp khác nhau ReadAllText. Quả thực câu trả lời bạn đề cập cho thấy ReadAllTextchỉ cần gọi StreamReader.ReadToEndnội bộ.
Ed Avis

169

Một so sánh điểm chuẩn của File.ReadAllLinesvs StreamReader ReadLinetừ xử lý C # tập tin

So sánh đọc tệp

Các kết quả. StreamReader nhanh hơn nhiều đối với các tệp lớn có hơn 10.000 dòng, nhưng sự khác biệt đối với các tệp nhỏ hơn là không đáng kể. Như mọi khi, hãy lập kế hoạch cho các kích cỡ khác nhau của tệp và chỉ sử dụng File.ReadAllLines khi hiệu suất không quan trọng.


Cách tiếp cận StreamReader

File.ReadAllTextcách tiếp cận đã được đề xuất bởi những người khác, bạn cũng có thể thử nhanh hơn (Tôi chưa kiểm tra định lượng về tác động hiệu suất, nhưng dường như nhanh hơn File.ReadAllText(xem so sánh bên dưới)). Sự khác biệt về hiệu suất sẽ chỉ hiển thị trong trường hợp các tệp lớn hơn.

string readContents;
using (StreamReader streamReader = new StreamReader(path, Encoding.UTF8))
{
     readContents = streamReader.ReadToEnd();
}


So sánh File.Readxxx () so với StreamReader.Readxxx ()

Xem mã biểu hiện qua ILSpy tôi đã tìm thấy những điều sau về File.ReadAllLines, File.ReadAllText.

  • File.ReadAllText - Sử dụng StreamReader.ReadToEndnội bộ
  • File.ReadAllLines - Cũng sử dụng StreamReader.ReadLinenội bộ với chi phí bổ sung để tạo List<string>trả về dưới dạng các dòng đọc và lặp cho đến cuối tệp.


Vì vậy, cả hai phương pháp là một lớp tiện lợi bổ sung được xây dựng trên đầu trang StreamReader. Điều này là hiển nhiên bởi cơ thể chỉ định của phương pháp.

File.ReadAllText() triển khai như được dịch ngược bởi 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;
}

2
Bạn có so sánh với File.ReadAllTextquá không ??
marc_s

2
ILSpy cho rằng đó File.ReadAllText()chỉ đơn giản là một trình bao bọc StreamReader.ReadToEnd(). Tôi đoán rằng lớp bổ sung sẽ hoạt động chậm hơn một chút StreamReader.ReadToEnd().
Devendra D. Chavan

Câu trả lời chính xác. Có lẽ một chút giải thích cho những người chỉ tìm kiếm sửa chữa, nhưng nó xứng đáng ít nhất là nhiều phiếu như câu trả lời đã chọn.
Sandy Gifford

@Devendra D. Chavan: Offtopic, nhưng tôi có thể tìm tài liệu tham khảo hoặc tài liệu cho ILSpy ở đâu?
Viral Jain

1
Bạn cũng có thể tìm thấy mã ở đây: Referenceource.microsoft.com/#mscorlib/system/io/iêu . Những gì tôi không nhận được, là tại sao có sự khác biệt đáng kể về tốc độ này nếu ReadAllTextchỉ là một trình bao bọc cho streamReader.ReadToEnd();?
Olivier Jacot-Descombes


6

Hãy xem phương thức File.ReadAllText ()

Một số lưu ý quan trọng:

Phương thức này mở một tệp, đọc từng dòng của tệp và sau đó thêm từng dòng dưới dạng một phần tử của chuỗi. Sau đó nó đóng tập tin. Một dòng được định nghĩa là một chuỗi các ký tự theo sau là trả về vận chuyển ('\ r'), nguồn cấp dữ liệu ('\ n') hoặc trả về vận chuyển ngay lập tức theo nguồn cấp dữ liệu. Chuỗi kết quả không chứa kết thúc vận chuyển kết thúc và / hoặc nguồn cấp dữ liệu.

Phương pháp này cố gắng tự động phát hiện mã hóa của một tệp dựa trên sự hiện diện của các dấu thứ tự byte. Các định dạng mã hóa UTF-8 và UTF-32 (cả endian lớn và endian nhỏ) có thể được phát hiện.

Sử dụng quá tải phương thức ReadAllText (Chuỗi, Mã hóa) khi đọc các tệp có thể chứa văn bản đã nhập, vì các ký tự không được nhận dạng có thể không được đọc chính xác.

Xử lý tệp được đảm bảo được đóng bằng phương pháp này, ngay cả khi ngoại lệ được đưa ra


6

string text = File.ReadAllText("Path");bạn có tất cả văn bản trong một biến chuỗi. Nếu bạn cần từng dòng riêng lẻ, bạn có thể sử dụng:

string[] lines = File.ReadAllLines("Path");

4
System.IO.StreamReader myFile =
   new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();

4

@Cris xin lỗi. Đây là trích dẫn MSDN Microsoft

Phương pháp luận

Trong thí nghiệm này, hai lớp sẽ được so sánh. Lớp StreamReaderFileStreamlớp sẽ được hướng dẫn để đọc toàn bộ hai tệp 10K và 200K từ thư mục ứng dụng.

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()

Kết quả

nhập mô tả hình ảnh ở đây

FileStreamrõ ràng là nhanh hơn trong thử nghiệm này. Phải mất thêm 50% thời gian StreamReaderđể đọc tệp nhỏ. Đối với tệp lớn, phải mất thêm 27% thời gian.

StreamReaderđặc biệt tìm kiếm ngắt dòng trong khi FileStreamkhông. Điều này sẽ chiếm một số thời gian thêm.

khuyến nghị

Tùy thuộc vào những gì ứng dụng cần làm với một phần dữ liệu, có thể có phân tích cú pháp bổ sung sẽ yêu cầu thời gian xử lý bổ sung. Xem xét một kịch bản trong đó một tệp có các cột dữ liệu và các hàng được CR/LFphân tách. Việc StreamReadernày sẽ làm việc xuống dòng văn bản tìm kiếm CR/LF, và sau đó ứng dụng sẽ thực hiện phân tích cú pháp bổ sung tìm kiếm một vị trí cụ thể của dữ liệu. (Bạn có nghĩ String. SubString không có giá không?)

Mặt khác, việc FileStreamđọc dữ liệu theo từng khối và một nhà phát triển chủ động có thể viết logic hơn một chút để sử dụng luồng cho lợi ích của mình. Nếu dữ liệu cần thiết nằm ở các vị trí cụ thể trong tệp, đây chắc chắn là cách để đi vì nó làm giảm mức sử dụng bộ nhớ.

FileStream là cơ chế tốt hơn cho tốc độ nhưng sẽ mất nhiều logic hơn.


Nhưng còn cái gì StreamReader.ReadToEnd?
Owen Blacker

3

cũng là cách nhanh nhất có nghĩa với mã C # ít nhất có thể là cái này:

string readText = System.IO.File.ReadAllText(path);

3

nếu bạn muốn chọn tệp từ thư mục Bin của ứng dụng thì bạn có thể thử làm theo và đừng quên xử lý ngoại lệ.

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

3

bạn có thể dùng :

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

2
string content = System.IO.File.ReadAllText( @"C:\file.txt" );

2

Đối với các noobs ngoài kia, những người tìm thấy công cụ này thú vị và thú vị, cách nhanh nhất để đọc toàn bộ tệp thành một chuỗi trong hầu hết các trường hợp ( theo các điểm chuẩn này ) là như sau:

using (StreamReader sr = File.OpenText(fileName))
{
        string s = sr.ReadToEnd();
}
//you then have to process the string

Tuy nhiên, tổng thể nhanh nhất để đọc một tệp văn bản có vẻ như sau:

using (StreamReader sr = File.OpenText(fileName))
{
        string s = String.Empty;
        while ((s = sr.ReadLine()) != null)
        {
               //do what you have to here
        }
}

Chống lại một số kỹ thuật khác , nó đã thắng hầu hết thời gian, bao gồm cả chống lại BufferedReader.


Nhận xét là muộn tôi biết, nhưng một chút bối rối về điểm chuẩn của bạn ở đây và trên trang được liên kết. Nó dường như chỉ kiểm tra tốc độ đọc và không tải vào toàn bộ chuỗi. Đoạn mã thứ hai đang đọc một dòng tại một thời điểm và không thực hiện bất kỳ việc nối thêm nào, vì vậy "làm những gì bạn phải ở đây" sẽ cần phải có trình tạo chuỗi hoặc chuỗi để giữ dữ liệu. Tại thời điểm đó, bộ nhớ được sử dụng để thêm nhiều dữ liệu sẽ thay đổi kết quả kiểm tra. Vì vậy, s thường sẽ có cùng kích thước giả sử một tệp có chiều rộng cố định để bộ nhớ sẽ được đặt cho kích thước của một dòng và dữ liệu sẽ không cần phải được sao chép sang bộ nhớ mới.
Charles Byrne

2

Bạn có thể sử dụng như thế này

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

Hy vọng điều này sẽ giúp bạn.


0

bạn có thể đọc một văn bản từ một tệp văn bản thành chuỗi như sau

string str = "";
StreamReader sr = new StreamReader(Application.StartupPath + "\\Sample.txt");
while(sr.Peek() != -1)
{
  str = str + sr.ReadLine();
}

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

                  }
              }
          }
      }
    }

0

Tôi đã thực hiện một so sánh giữa ReadAllText và StreamBuffer cho một csv 2Mb và có vẻ như sự khác biệt là khá nhỏ nhưng ReadAllText dường như chiếm thế thượng phong từ những lần thực hiện để hoàn thành các chức năng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.