我已经下载了一个从Azure Blob Storage录制的JSON文件。文件大小为137MB。
当我选择"使用Notepad ++"编辑时,大约需要1-2秒。从文件上下文菜单。因此,我决定创建一个程序,将JSON转换器转换为CSV文件格式。但似乎,我遇到了某种例外。目前,为了查看JSON内容,我将在RichTextBox中显示,因为它可以在我决定转换为CSV之前查看内容。
开始加载的事件: -
private async Task<bool> LoadJSONtoRTB(string path)
{
try
{
foreach (var line in File.ReadLines(path))
{
rtbjson.Text = line;
}
await Task.Delay(10);
return true;
}
catch (Exception)
{
return false;
}
}
我尝试过的代码面临异常: -
第一种方法: 第一个代码:
private async Task<bool> LoadJSONtoRTB(string path)
{
try
{
using (FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
using (StreamReader sr = new StreamReader(bs))
{
string line;
while ((line = sr.ReadLine()) != null)
{
rtbjson.AppendText(line);
}
}
await Task.Delay(10);
return true;
}
catch (Exception)
{
return false;
}
}
第二段代码:
private async Task<bool> LoadJSONtoRTB(string path)
{
try
{
StreamReader sr = new StreamReader(@path);
while (!sr.EndOfStream)
rtbjson.Text += sr.ReadLine();
await Task.Delay(10);
return true;
}
catch (Exception)
{
return false;
}
}
例外:类型&#39; System.AccessViolationException&#39;的未处理异常发生在System.Windows.Forms.dll
中附加信息:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
第二种方法: -
{{1}}
使用上面的代码,当我设置断点以查看进度时,它运行大约12分钟。
12分钟,长度为600万。
是否有任何方法可以显示文本文件(json / txt),其中包含6400万字符长度的示例,如记事本++只需1-2秒即可查看文件?
答案 0 :(得分:2)
我怀疑Notepad ++将整个文件加载到内存中,等同于System.IO.File.ReadAllText
。此外,将文件的每一行附加到字符串没有任何好处,最终结果是占用相同的内存。
使用RichTextBox,您可以做的最好的事情是:
richTextBox1.Text = System.IO.File.ReadAllText(filePath);
无论如何,Notepad ++使用比RichTextBox更快的Scintilla。
您可以尝试使用ScintillaNET作为Scintilla的包装器。
您可以像使用RichTextBox一样设置控制文本:
scintilla1.Text = System.IO.File.ReadAllText(filePath);
答案 1 :(得分:1)
您的LoadJSONtoRTB方法异步运行。因此,您尝试从错误的线程更新gui(文本框)。 这种方法将帮助您在正确的线程上运行gui更新:
this.Invoke(new Action(() => { rtbjson.Text += sr.ReadLine(); }));
当然,有更多有效的方法用StringBuilder等大量文本填充控件。 重要的一点就是永远更新gui线程上的gui。 这可以通过运行Form.Invoke
来完成