将文本文件读入字符串变量的最快方法是什么?
我知道它可以通过多种方式完成,例如读取单个字节,然后将它们转换为字符串。我正在寻找一种编码最少的方法。
C# file handling 中 File.ReadAllLines
与 StreamReader 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.ReadAllLines
、File.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
比较过吗??
File.ReadAllText()
只是对 StreamReader.ReadToEnd()
的包装。我猜测附加层的执行速度应该比 StreamReader.ReadToEnd()
稍慢。
ReadAllText
只是 streamReader.ReadToEnd();
的包装器,为什么速度会有如此显着的差异?
查看 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 的比赛。
string text = File.ReadAllText("Path");
您将所有文本都放在一个字符串变量中。如果您需要单独的每一行,您可以使用它:
string[] lines = File.ReadAllLines("Path");
System.IO.StreamReader myFile =
new System.IO.StreamReader("c:\\test.txt");
string myString = myFile.ReadToEnd();
@Cris 抱歉。这是引用 MSDN Microsoft
方法
在本实验中,将比较两个班级。 StreamReader
和 FileStream
类将被引导从应用程序目录中读取两个 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
呢?
如果您想从应用程序的 Bin 文件夹中选择文件,那么您可以尝试以下操作,并且不要忘记进行异常处理。
string content = File.ReadAllText(Path.Combine(System.IO.Directory.GetCurrentDirectory(), @"FilesFolder\Sample.txt"));
用最少的 C# 代码表示的最快的方法可能是这个:
string readText = System.IO.File.ReadAllText(path);
您可以使用 :
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);
}
}
string content = System.IO.File.ReadAllText( @"C:\file.txt" );
你可以这样使用
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 "";
}
}
希望这会帮助你。
您也可以将文本文件中的文本读入字符串,如下所示
string str = "";
StreamReader sr = new StreamReader(Application.StartupPath + "\\Sample.txt");
while(sr.Peek() != -1)
{
str = str + sr.ReadLine();
}
我对 2Mb csv 的 ReadAllText 和 StreamBuffer 进行了比较,似乎差异很小,但 ReadAllText 似乎从完成功能所需的时间上占了上风。
StreamReader.ReadToEnd
更有效。StreamReader.ReadToEnd
比ReadAllLines
更有效。这是意料之中的,因为后者还将文本分成几行。但我们讨论的是另一种方法,ReadAllText
。实际上,您提到的答案表明ReadAllText
只是在内部调用StreamReader.ReadToEnd
。