【问题标题】:How to show progress bar while reading multiple text files如何在阅读多个文本文件时显示进度条
【发布时间】:2016-02-05 20:59:41
【问题描述】:

我正在从子文件夹中逐行读取文本文件。这意味着一旦它完成了包含一个子文件夹的所有文本文件的读取,然后开始从下一个子文件夹读取文件。你可以从我的代码中理解。一切正常,我想要的是在从第一个文件开始读取时显示进度条,然后在执行完成时隐藏进度条。任何帮助都将不胜感激。以下是我的代码:

private void browse_Click(object sender, EventArgs e)
    {
        try
        {
            string newFileName1 = "";
            string newFileName2 = "";
            week = textBox2.Text;
            if (week == null || week == "")
            {
                MessageBox.Show("Week cannot be null.");
                return;
            }


            DialogResult result = folderBrowserDialog1.ShowDialog();

            if (result == DialogResult.OK)
            {
                DateTime starttime = DateTime.Now;

                string folderPath = Path.GetDirectoryName(folderBrowserDialog1.SelectedPath);
                string folderName = Path.GetFileName(folderPath);
                DirectoryInfo dInfo = new DirectoryInfo(folderPath);

                foreach (DirectoryInfo folder in dInfo.GetDirectories())
                {
                    newFileName1 = "Files_with_dates_mismatching_the_respective_week_" + folder.Name + ".txt";
                    newFileName2 = "Files_with_wrong_date_format_" + folder.Name + ".txt";

                    if (File.Exists(folderPath + "/" + newFileName1))
                    {
                        File.Delete(folderPath + "/" + newFileName1);
                    }

                    if (File.Exists(folderPath + "/" + newFileName2))
                    {
                        File.Delete(folderPath + "/" + newFileName2);
                    }

                    FileInfo[] folderFiles = folder.GetFiles();

                    if (folderFiles.Length != 0)
                    {
                        List<Task> tasks = new List<Task>();
                        foreach (var file in folderFiles)
                        {
                            var task = ReadFile(file.FullName, folderPath, folder.Name, week);
                            tasks.Add(task);
                        }

                        Task.WhenAll(tasks.ToArray());
                        DateTime stoptime = DateTime.Now;
                        TimeSpan totaltime = stoptime.Subtract(starttime);
                        label6.Text = Convert.ToString(totaltime);
                        textBox1.Text = folderPath;

                    }
                }
                DialogResult result2 = MessageBox.Show("Read the files successfully.", "Important message", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        catch (Exception)
        {

            throw;
        }
    }

    public async Task ReadFile(string file, string folderPath, string folderName, string week)
    {
        int LineCount = 0;
        string fileName = Path.GetFileNameWithoutExtension(file);

        using (FileStream fs = File.Open(file, FileMode.Open))
        using (BufferedStream bs = new BufferedStream(fs))
        using (StreamReader sr = new StreamReader(bs))
        {
            for (int i = 0; i < 2; i++)
            {
                sr.ReadLine();
            }

            string oline;
            while ((oline = sr.ReadLine()) != null)
            {
                LineCount = ++LineCount;
                string[] eachLine = oline.Split(';');

                string date = eachLine[30].Substring(1).Substring(0, 10);

                DateTime dt;

                bool valid = DateTime.TryParseExact(date, "dd/MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt);

                if (!valid)
                {
                    StreamWriter sw = new StreamWriter(folderPath + "/" + "Files_with_wrong_date_format_" + folderName + ".txt", true);
                    await sw.WriteLineAsync(fileName + "  " + "--" + "  " + "Line number :" + " " + LineCount);
                    sw.Close();
                }
                else
                {
                    DateTime Date = DateTime.ParseExact(date, "d/M/yyyy", CultureInfo.InvariantCulture);

                    int calculatedWeek = new GregorianCalendar(GregorianCalendarTypes.Localized).GetWeekOfYear(Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Saturday);

                    if (calculatedWeek == Convert.ToInt32(week))
                    {

                    }
                    else
                    {
                        StreamWriter sw = new StreamWriter(folderPath + "/" + "Files_with_dates_mismatching_the_respective_week_" + folderName + ".txt", true);
                        await sw.WriteLineAsync(fileName + "  " + "--" + "  " + "Line number :" + " " + LineCount);
                        sw.Close();
                    }
                }
            }
        }
    }

【问题讨论】:

  • 这样是不可能的,因为在子文件夹遍历之前你不知道你有多少文件。如果你想拥有真实的进度条,你必须遍历子文件夹并填充文件集合,然后读取文件。
  • 旁注:没有awaitTask.WhenAll 对代码没有影响,所以我怀疑“一切正常”

标签: c# winforms


【解决方案1】:

您是要显示每个文件本身的进度,还是显示所有文件的进度?

您可以通过以下方式获取文件大小:

FileInfo fileInfo = new FileInfo(file);
long fileLength = fileInfo.Length;

将进度条最小值设置为 0,最大值设置为 100。 创建一个包含当前流位置的变量,然后更新进度条:

(int)(((decimal)currentStreamPosition / (decimal)fileLength)*(decimal)100);

您可以添加所有文件大小并显示百分比,或者在完成读取一个文件时将 currentStreamPosition 设置为零。

您必须遍历所有需要读取的文件,然后才能获得确切的文件大小。

【讨论】:

  • 我想要一个所有文件。
  • 那么你必须在遍历时添加所有文件大小,然后在读取一个文件后将 currentStreamPosition 变量设置为零。
  • 您应该在后台工作人员中执行此操作并使用更新进度来显示 ui 中的更改,否则 ui 线程将挂起直到进程完成并且进度条不会更新
【解决方案2】:

通常,在类似情况下,如果可能,最好显示 2 个进度条 - 一个用于总体进度,另一个用于当前。因此,您可以先计算所有子文件夹中的所有文件以估计总体进度,然后在当前进度栏中显示每个文件的读取。

如果进度条应该只有一个 - 则只能显示总体进度。 您可以使用 Directory.GetFiles 方法计算文件数。请参阅以下链接 https://msdn.microsoft.com/en-us/library/3hwtke0f.aspx

【讨论】:

    猜你喜欢
    • 2014-06-03
    • 2021-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    相关资源
    最近更新 更多