【发布时间】:2017-01-20 09:12:23
【问题描述】:
我已经下载了一个从 Azure Blob 存储中记录的 JSON 文件。文件大小为 137MB。
当我从文件上下文菜单中选择“使用 Notepad++ 编辑”时,大约需要 1-2 秒。因此,我决定创建一个程序来将 JSON 转换器转换为 CSV 文件格式。但似乎,我遇到了某种例外。目前,为了查看 JSON 内容,我将显示在 RichTextBox 中,因为它可以在我决定转换为 CSV 之前查看内容。
开始加载的事件:-
private async void txtjsonname_DoubleClick(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "JSON Files (*.json)|*.json";
ofd.InitialDirectory = @"C:\";
ofd.Title = "Select single json file to be converted";
ofd.Multiselect = false;
if (ofd.ShowDialog() == DialogResult.OK)
{
rtbstat.Text = null;
txtcsvname.Text = null;
txtjsonname.Text = null;
lblcsvpath.Text = null;
lbljsonpath.Text = null;
rtbjson.Clear();
txtjsonname.Text = Path.GetFileName(ofd.FileName);
lbljsonpath.Text = Path.GetDirectoryName(ofd.FileName);
if (await LoadJSONtoRTB(ofd.FileName))
{
rtbjson.WordWrap = false;
rtbstat.Text = "Load file finished! " + (rtbjson.Lines.Count()).ToString() + " line(s) detected | " + rtbjson.Text.Length.ToString() + " character(s) detected";
txtcsvname.Text = Path.GetFileNameWithoutExtension(ofd.FileName) + ".csv";
}
}
await Task.Delay(1000);
}
我尝试遇到异常的代码:-
第一种方法: 第一个代码:
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;
}
}
异常:System.Windows.Forms.dll 中出现“System.AccessViolationException”类型的未处理异常
附加信息:试图读取或写入受保护的内存。这通常表明其他内存已损坏。
第二种方法:-
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;
}
}
使用上面的代码,当我放置断点以查看进度时,它运行了大约 12 分钟。
12 分钟,阅读长度为 600 万。
有没有什么方法可以显示文本文件(json/txt),例如notepad++只需要1-2秒就可以查看文件?
【问题讨论】:
-
这样的操作:
rtbjson.Text += sr.ReadLine();对大量文本的字符串非常慢,因为在每一步它都会为该操作的结果创建新变量。而是尝试使用 StringBuilder 和 AppendText 方法,让我知道它是如何工作的 -
你能发布完整的异常堆栈跟踪吗?
-
第一种方法可能比第二种方法好。如果在添加行时禁用图形更新怎么办?见How do you prevent a RichTextBox from refreshing its display?。
-
另外,
RichTextBox.LoadFile()可能会有所帮助。见C# - Read in a large (150MB) text file into a Rich Text Box。 -
标准 Windows 控件专为正常数量的文本而设计。支持大量文本的编辑器专为此目的而设计。