ChatGPT解决这个技术问题 Extra ChatGPT

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

将文本文件读入字符串变量的最快方法是什么?

我知道它可以通过多种方式完成,例如读取单个字节,然后将它们转换为字符串。我正在寻找一种编码最少的方法。


K
KyleMit

File.ReadAllText 怎么样:

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

不过,这不是最好的功能。正如 Devendra D. Chavan 在他的回答中指出的那样,StreamReader.ReadToEnd 更有效。
@OwenBlacker这取决于“最快”是指“执行时间最短”还是“理解时间最短”。
File.ReadAllText 绝对是最容易使用的,但正如“Devendra D. Chavan”所指出的,它并不是最快的。因此,如果您正在阅读小文件,那么使用 File.ReadAllText 将是一个更好的选择。它实际上取决于您正在阅读的文本文件有多大。
从服务器读取检查 this,希望对某人有所帮助。
@OwenBlacker——你确定吗?基准测试表明 StreamReader.ReadToEndReadAllLines 更有效。这是意料之中的,因为后者还将文本分成几行。但我们讨论的是另一种方法,ReadAllText。实际上,您提到的答案表明 ReadAllText 只是在内部调用 StreamReader.ReadToEnd
D
Devendra D. Chavan

C# file handlingFile.ReadAllLinesStreamReader ReadLine 的基准比较

https://i.stack.imgur.com/ojUyh.png

结果。 StreamReader 对于超过 10,000 行的大文件要快得多,但对于较小文件的差异可以忽略不计。与往常一样,计划不同大小的文件,仅在性能不重要时才使用 File.ReadAllLines。

StreamReader 方法

由于其他人建议使用 File.ReadAllText 方法,您也可以尝试更快(我没有对性能影响进行定量测试,但它似乎比 File.ReadAllText 更快(参见 比较下面))。但是,只有在文件较大的情况下才能看到性能方面的 difference

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 以作为读取行返回并循环到文件末尾的额外开销。


因此,这两种方法都是建立在 StreamReader 之上的额外的便利层。方法的指示性主体可以证明这一点。

由 ILSpy 反编译的 File.ReadAllText() 实现

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

你也和File.ReadAllText比较过吗??
ILSpy 建议 File.ReadAllText() 只是对 StreamReader.ReadToEnd() 的包装。我猜测附加层的执行速度应该比 StreamReader.ReadToEnd() 稍慢。
很好的答案。对于那些只是在寻找解决方案的人来说,也许有一点解释,但它至少应该得到与所选答案一样多的投票。
@Devendra D. Chavan:题外话,但我在哪里可以找到 ILSpy 的参考或文档?
您还可以在此处找到代码:referencesource.microsoft.com/#mscorlib/system/io/…。我不明白的是,如果 ReadAllText 只是 streamReader.ReadToEnd(); 的包装器,为什么速度会有如此显着的差异?
M
Mouna Cheikhna
string contents = System.IO.File.ReadAllText(path)

这是MSDN documentation


s
sll

查看 File.ReadAllText() 方法

一些重要的评论:

此方法打开一个文件,读取文件的每一行,然后将每一行添加为字符串的一个元素。然后它关闭文件。行定义为字符序列后跟回车符 ('\r')、换行符 ('\n') 或回车符后紧跟换行符。结果字符串不包含终止回车和/或换行。此方法尝试根据字节顺序标记的存在自动检测文件的编码。可以检测编码格式 UTF-8 和 UTF-32(big-endian 和 little-endian)。在读取可能包含导入文本的文件时使用 ReadAllText(String, Encoding) 方法重载,因为可能无法正确读取无法识别的字符。该方法保证文件句柄关闭,即使引发异常


佚名

对于那些觉得这些东西很有趣和有趣的菜鸟来说,在大多数情况下(according to these benchmarks)将整个文件读入字符串的最快方法是通过以下方式:

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

Put up against several other techniques,它大部分时间都赢了,包括与 BufferedReader 的比赛。


我知道评论晚了,但对您在此处和链接页面上的基准有点困惑。它似乎只是在测试读取速度,而不是加载到整个字符串中。第二个代码片段一次读取一行而不做任何附加,因此“在这里做你必须做的”需要有一个字符串构建器或字符串来保存数据。此时用于添加更多数据的内存会改变测试结果。因此,假设文件宽度固定,s 通常大小相同,因此内存将设置为一行的大小,并且不需要将数据复制到新内存中。
D
Dilshod

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

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

M
Maxim V. Pavlov
System.IO.StreamReader myFile =
   new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();

B
Baby Groot

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

结果

https://i.stack.imgur.com/wK6TW.jpg

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

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

建议

根据应用程序需要对一段数据执行的操作,可能会有额外的解析需要额外的处理时间。考虑文件具有数据列且行以 CR/LF 分隔的情况。 StreamReader 将沿着文本行查找 CR/LF,然后应用程序将执行额外的解析以查找数据的特定位置。 (你认为 String.SubString 是没有代价的吗?)

另一方面,FileStream 以块的形式读取数据,主动开发人员可以编写更多的逻辑来使用流以使其受益。如果所需的数据位于文件中的特定位置,这肯定是要走的路,因为它可以降低内存使用率。

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


但是 StreamReader.ReadToEnd 呢?
D
Deeps

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

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

D
Davide Piras

用最少的 C# 代码表示的最快的方法可能是这个:

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

E
Erwin Draconis

您可以使用 :

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

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

A
Amit Kumawat

你可以这样使用

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

希望这会帮助你。


S
Sai Kalyan Kumar Akshinthala

您也可以将文本文件中的文本读入字符串,如下所示

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

H
Hatitye Chindove

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