我正在寻找一种非常快速的方法,将文本内容从1GB文本文件加载到WPF控件(例如ListView
)。我想在 2秒内加载内容。
逐行读取内容需要很长时间,因此我认为将其作为字节读取会更快。到目前为止,我有:
byte[] buffer = new byte[4096];
int bytesRead = 0;
using(FileStream fs = new FileStream("myfile.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
while((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) {
Encoding.Unicode.GetString(buffer);
}
}
有没有办法将字节转换为字符串行并将它们添加到ListView / ListBox中?
这是将文件内容加载到WPF GUI控件的最快方法吗?有各种应用程序可以在1秒内从1GB文件加载文件内容。
编辑:使用多个线程读取文件会有帮助吗?例如:
var t1 = Task.Factory.StartNew(() =>
{
//read content/load into GUI...
});
编辑2:我打算按照下面的建议使用分页/分页,但是当我想向下或向上滚动时,必须读取文件内容< b>再次到达正在显示的地方..所以我想使用:
fs.Seek(bytePosition, SeekOrigin.Begin);
但是这会比在多个线程中逐行读取更快吗?例如:
long fileLength = fs.Length;
long halfFile = (fileLength / 2);
FileStream fs2 = fs;
byte[] buffer2 = new byte[4096];
int bytesRead2 = 0;
var t1 = Task.Factory.StartNew(() =>
{
while((bytesRead += fs.Read(buffer, 0, buffer.Length)) < (halfFile -1)) {
Encoding.Unicode.GetString(buffer);
//convert bytes into string lines...
}
});
var t2 = Task.Factory.StartNew(() =>
{
fs2.Seek(halfFile, SeekOrigin.Begin);
while((bytesRead2 += fs2.Read(buffer2, 0, buffer2.Length)) < (fileLength)) {
Encoding.Unicode.GetString(buffer2);
//convert bytes into string lines...
}
});
答案 0 :(得分:1)
使用线程不会使更快(从技术上来说,线程需要花费一些费用,因此加载可能会花费更长的时间),但它可能会使您的应用更具响应性。我不知道File.ReadAllText()
是否更快?
数据绑定会遇到问题。如果在从工作线程加载1GB文件后说出来(无论技术如何),您现在将有1GB的行数据绑定到ListView/ListBox
。我建议您不要循环,通过说ObservableCollection
逐行添加到您的控件。
相反,请考虑让工作线程将批量项目附加到您的UI线程,在该线程中,它可以将项目附加到批处理中每个项目的ListView / ListBox。
这会减少Invoke
的开销,因为它会充斥UI消息泵。
答案 1 :(得分:0)
由于您想要快速阅读,我建议您为WPF桌面应用程序使用System.IO.File类。
MyText = File.ReadAllText("myFile.txt", Encoding.Unicode); // If you want to read as is
string[] lines = File.ReadAllLines("myFile.txt", Encoding.Unicode); // If you want to place each line of text into an array
与DataBinding一起,您的WPF应用程序应该能够读取文本文件并快速在UI上显示它。
关于效果,您可以参考此answer。
因此,在创建代码时,请使用File.ReadAllText()而不是ReadToEnd() 更短,更可读。它还负责妥善处理 资源,因为你可能忘记使用StreamReader(正如你所做的那样) 你的片段)。 - 达林迪米特洛夫
此外,您必须考虑将运行您的应用程序的机器的规格。
答案 2 :(得分:0)
当你说&#34;逐行阅读内容需要很长时间&#34;,你的意思是什么?你是如何阅读内容的?
然而,最重要的是,让我们退后一步,看看将1 GB数据加载到ListView中的想法。
就个人而言,您应该使用IEnumerable
来读取文件,例如:
foreach (string line in File.ReadLines(path))
{
}
但更重要的是,您应该在用户界面中实施分页,并减少可见和立即加载的内容。这将大量减少您的资源使用,并确保您有一个可用的用户界面。您可以使用Skip()
and Take()
等IEnumerable方法,这些方法可以有效地使用您的资源(即不加载未使用的数据)。
你也不需要使用任何额外的线程(除了后台线程+ UI线程),但我建议使用MVVM和INotifyPropertyChanged来完全避免担心线程。