如何使用C#将整个文件读取为字符串?


Answers:


373

怎么样File.ReadAllText

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

3
不过,这并不是最好的功能。正如Devendra D. Chavan在回答中指出的那样,StreamReader.ReadToEnd效率更高。
Owen Blacker 2014年

40
@OwenBlacker取决于“最快速”是指“最短执行时间”还是“最短理解时间”。
bonh 2015年

2
File.ReadAllText绝对是最容易使用的文件,但是正如“ Devendra D. Chavan”所指出的那样,它并不是最快的文件。因此,如果您正在读取小文件,那么使用File.ReadAllText。会是一个更好的选择,它实际上取决于您正在读取的文本文件的大小。
Mana 2015年

为了从服务器读取查询,希望可以帮助别人。
shaijut

1
@OwenBlacker-您确定吗?基准测试显示StreamReader.ReadToEnd比效率更高ReadAllLines。这是可以预期的,因为后者还将文本分成几行。但是,我们正在谈论另一种方法ReadAllText。确实,您提到的答案表明ReadAllText只是StreamReader.ReadToEnd内部调用。
Ed Avis

169

的基准比较File.ReadAllLinesVS StreamReader ReadLineC#文件处理

文件读取比较

结果。对于具有10,000多个行的大型文件,StreamReader的速度要快得多,但是较小文件的差异可以忽略不计。与往常一样,计划不同大小的文件,并且仅在性能不是很关键的情况下才使用File.ReadAllLines。


StreamReader方法

正如File.ReadAllText其他人所建议的那样,您也可以尝试更快(我尚未对性能影响进行定量测试,但它似乎比File.ReadAllText(参见下面的比较)要快)。但是 ,只有在文件较大的情况下,性能的差异才可见。

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


File.Readxxx()与StreamReader.Readxxx()的比较

查看指示代码通过ILSpy我已经找到了以下有关File.ReadAllLinesFile.ReadAllText

  • File.ReadAllText - StreamReader.ReadToEnd内部使用
  • File.ReadAllLines -还用于StreamReader.ReadLine创建额外的内部开销,List<string>以作为读取行返回并循环到文件末尾。


因此,这两种方法都是在之上构建的附加便利层StreamReader。这通过该方法的指示性主体是显而易见的。

File.ReadAllText() 由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
您也与之作比较File.ReadAllText吗?
marc_s

2
ILSpy建议这File.ReadAllText()仅仅是对它的包装StreamReader.ReadToEnd()。我猜想额外的层应该比慢一点StreamReader.ReadToEnd()
Devendra D. Chavan

好答案。对于只寻找解决方案的人来说,也许有一些解释,但它至少应与所选答案一样多。
桑迪·吉福德

@Devendra D. Chavan:脱位,但是在哪里可以找到ILSpy的参考或文档?
病毒Ja那教徒

1
您也可以在这里找到代码:referencesource.microsoft.com/#mscorlib/system/io/…。我不明白的是,如果ReadAllText仅仅是包装的原因,为什么速度会有如此显着的差异streamReader.ReadToEnd();
奥利维尔·雅各布·德斯科姆斯


6

看看File.ReadAllText()方法

一些重要的评论:

此方法打开一个文件,读取文件的每一行,然后将每一行添加为字符串的元素。然后关闭文件。行定义为一个字符序列,后跟一个回车符('\ r'),一个换行符('\ n')或一个回车符后紧跟一个换行符。结果字符串不包含回车符和/或换行符。

此方法尝试根据字节顺序标记的存在自动检测文件的编码。可以检测到UTF-8和UTF-32编码格式(大端和小端)。

读取可能包含导入文本的文件时,请使用ReadAllText(String,Encoding)方法重载,因为无法识别的字符可能无法正确读取。

即使引发异常,也可以通过此方法确保关闭文件句柄


6

string text = File.ReadAllText("Path");您将所有文本都放在一个字符串变量中。如果您需要单独使用每一行,则可以使用以下命令:

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


4

@Cris对不起。这是报价 MSDN Microsoft

方法

在此实验中,将比较两个类别。在StreamReaderFileStream类将直接从应用程序目录全部读取10K和200K的两个文件。

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

结果

在此处输入图片说明

FileStream显然在此测试中速度更快。StreamReader读取小文件需要花费额外的50%时间。对于大文件,需要花费额外的27%的时间。

StreamReader是专门寻找换行符,而FileStream不是。这将占一些额外的时间。

推荐建议

根据应用程序需要处理数据的一部分,可能会有其他解析,这将需要更多处理时间。考虑一个文件具有数据列并且行被CR/LF分隔的情况。该StreamReader会的工作下来的文字寻找行CR/LF,然后应用程序会做额外的解析寻找数据的特定位置。(您是否认为String。SubString没有价格?)

另一方面,FileStream读取会分块读取数据,而积极的开发人员可以编写更多的逻辑以使用该流来受益。如果所需的数据在文件中的特定位置,则肯定会采用这种方法,因为它可以减少内存使用量。

FileStream 是更好的速度机制,但需要更多逻辑。


但是呢StreamReader.ReadToEnd
Owen Blacker 2014年


3

如果要从应用程序的Bin文件夹中选择文件,则可以尝试以下操作,并且不要忘记进行异常处理。

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

3

您可以使用 :

 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

对于那里的新手来说,这很有趣和有趣,在大多数情况下(根据这些基准),将整个文件读入字符串的最快方法是:

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

但是,总体上,读取文本文件最快的速度如下所示:

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

抵制其他几种技术,它在大多数情况下都赢了,包括与BufferedReader对抗。


我知道评论已经晚了,但是您对这里和链接页面的基准测试有些困惑。它似乎仅测试读取速度,而不是加载到整个字符串中。第二个代码段是一次读取一行,并且不进行任何附加操作,因此“要做在这里要做的事情”将需要一个字符串生成器或字符串来保存数据。此时,用于添加更多数据的内存将更改测试结果。因此,假设文件具有固定宽度,s通常是相同的大小,因此将为行的大小设置内存,并且不需要将数据复制到新的内存中。
查尔斯·伯恩

2

你可以这样使用

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

希望这会帮助你。


0

您也可以从文本文件中读取文本到字符串中,如下所示

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

我对2Mb csv的ReadAllText和StreamBuffer进行了比较,似乎差异很小,但ReadAllText似乎在完成功能上占了上风。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.