我有一个非常大的CSV文件(~5.5GB),我试图通过这个文件来显示行数,看看完成这个过程需要多长时间。我遇到的问题是,因为它是一个大文件,每当我尝试读取我的应用程序挂起的文件时,可能是它正忙着阅读或者只是冻结。所以我想集成一个后台工作者来显示我的应用程序的进度。
我有ProgressBar (pb)
,Label (label1)
,TextBox (textBox1)
和Button (button)
我的应用程序代码如下所示:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = @"\\svr\CreFiles\ndaa_2011.csv";
}
private void button1_Click(object sender, EventArgs e)
{
int i = 0;
BackgroundWorker worker;
worker = new BackgroundWorker { WorkerReportsProgress = true };
worker.DoWork += (senders, args) =>
{
using (TextFieldParser parser = new TextFieldParser(textBox1.Text))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
while (!parser.EndOfData)
{
//Processing row
string[] fields = parser.ReadFields();
foreach (string field in fields)
{
//TODO: Process field
i++; //add 1 to i for each row to get a total row count
label1.Invoke((MethodInvoker) delegate
{
label1.Text = "" + i;
});
worker.ReportProgress(i); //maybe the calculation needs to be different?
}
}
}
};
worker.ProgressChanged += (senders, args) =>
{
pb.Value = Math.Min(args.ProgressPercentage, 100); //maybe this needs to change?
};
worker.RunWorkerAsync();
}
我运行了该应用程序,我发现ProgressBar
没有任何变化。
我想要做的是根据行数,进度应该从0到100%变化的行数。
我的代码是否需要以任何方式进行修改?
更新:
我更新了我的问题,并在foreach
语句中添加了标签和后台工作人员进度,标签正在更改显示它正在读取的行数。但是如何找到进度的计算?一旦我按下按钮,进度条就会填满。
答案 0 :(得分:2)
首先,您使用i
值(即行号)来报告应用程序的进度,除非文件正好是100行,否则会产生错误的百分比计算。
作业需要多长时间的唯一指示是您正在处理的文件的长度;但是,此长度在bytes
中,并且每一行都不完全对应于特定的字节数。您可以使用ASCII编码计算每个byte
行的string
个数{@ 1}}每个char
采用byte
的事实(这可能是Unicode的变化,每个字符1,2或4个字节)。您可以使用该值根据累积总和和文件长度更新百分比。
答案 1 :(得分:2)
在阅读纯文本时,我假设您可以使用方法Encoding.Default.GetByteCount(string)
获取正在阅读的字节数。使用它可以总结以字节为单位读取的数据量。 修改:或者,不要使用默认编码,而是在此处对文件进行编码。
您还可以以字节为单位获取当前文件的文件大小,只需使用适当的文件系统方法。
您需要的更新量完全取决于您,您可以每100次读取,每100行,每100次,等等。
您可以将进度条设置为(NumberBytesRead/NumberBytesTotal)*100
来更新进度条
这将为您提供读取字节的百分比。您可能希望添加逗号,换行符和其他内容的偏移量以根据需要更正计算。