C#将文本数据加载到WPF控件中

时间:2016-02-15 01:43:45

标签: c# wpf file

我正在寻找一种非常快速的方法,将文本内容从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...
    }
});

3 个答案:

答案 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来完全避免担心线程。