簡體   English   中英

使用C#進行文件分割的問題

[英]Issues with file splitting with c#

我一直在嘗試制作一個程序,將較大的文本文件拆分為較小的部分,以便於使用。

我目前有兩個問題,無法弄清楚是怎么回事。

問題1:后台工作者有時會解雇多次。 我似乎無法弄清為什么決定運行多少次。 它將運行拆分,並在最終文件上似乎循環回到工作開始並再次運行。 它還會觸發多個完成工作的任務。 如果我將分割的文件數設置為不同的數,則事情變得復雜,后台工作程序似乎可以激發不同的次數,但它與文件數沒有直接關系。 有時相同數量的文件會導致后台工作程序僅觸發一次,有時則觸發多次。

問題2:有時,拆分將不會創建所有文件。 如果運行某些文件,它將創建前兩個文件,然后刪除其余文件。 似乎只有在將數字設置為3個文件時才發生。 如果我把行數加起來,它應該正確相等。 所以我不確定那里發生了什么。

調用線程

private void StartSplit()
    {
        if (int.TryParse(NumberOfFilesTB.Text, out _numberOfFiles))
        {
            if (bg.IsBusy)
            {
                ((MainWindow)Application.Current.MainWindow).SetStatus("Warning",
                    "Please only run one split process at a time.");
                return;
            }

            ((MainWindow)Application.Current.MainWindow).DisplayAlert(
                "Split is running, you will receive an alert when it has finished. You may use other tools while the split is running.");

            var args = new List<string> { _filepath, _includeHeaders.ToString(), _numberOfFiles.ToString() };
            bg.DoWork += bg_DoWork;
            bg.WorkerReportsProgress = true;
            bg.ProgressChanged += ProgressChanged;
            bg.RunWorkerCompleted += bg_RunWorkerCompleted;
            bg.WorkerSupportsCancellation = true;
            bg.RunWorkerAsync(args);
            ProcessText.Text = "Running split process";
        }
        else
        {
            ((MainWindow)Application.Current.MainWindow).SetStatus("Warning", "Please enter a number for number of files");
        }
    }

后台線程

  private void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        var args = e.Argument as List<string>;
        string filepath = args[0];
        string includeHeaders = args[1];
        int numberOfFiles = Convert.ToInt32(args[2]);
        int numberOfRows = _lineCount / numberOfFiles;
        _tempath = Path.GetDirectoryName(_filepath);
        Directory.CreateDirectory(_tempath+"\\split");

        if (includeHeaders == "True")
        {
            using (var reader = new StreamReader(File.OpenRead(filepath)))
            {
                _lines.Clear();
                _header = reader.ReadLine();
                _lines.Add(_header);

                for (int i = 0; i < _lineCount; i++)
                {

                    if (bg.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }

                    int percentage = (i + 1) * 100 / _lineCount;

                    bg.ReportProgress(percentage);

                    _lines.Add(reader.ReadLine());

                    if (i % numberOfRows == 0)
                    {
                        _counter++;
                        Debug.WriteLine(i);

                        if (i == 0)
                        {
                            //skip first iteration 
                            _counter = 0;
                            continue;

                        }
                        _output = _tempath + "\\" + "split\\" + _fileNoExt + "_split-" + _counter + _fileExt;
                        _filesMade.Add(_output);
                        File.WriteAllLines(_output, _lines.ConvertAll(Convert.ToString));
                        _lines.Clear();
                        _lines.Add(_header);
                    }
                }
            }
        }
        else
        {
            using (var reader = new StreamReader(File.OpenRead(filepath)))
            {
                _lines.Clear();
                _header = reader.ReadLine();
                _lines.Add(_header);
                for (int i = 0; i < _lineCount; i++)
                {
                    if (bg.CancellationPending)
                    {
                        e.Cancel = true;
                        break;
                    }

                    int percentage = (i + 1) * 100 / _lineCount;
                    bg.ReportProgress(percentage);
                    _lines.Add(reader.ReadLine());

                    if (i % numberOfRows == 0)
                    {
                        _counter++;

                        if (i == 0)
                        {
                            //skip first iteration
                            _counter = 0;
                            continue;
                        }
                        string output = _tempath + "\\" + "split\\" + _fileNoExt + "_split-" + _counter + _fileExt;
                        _filesMade.Add(_output);
                        File.WriteAllLines(output, _lines.ConvertAll(Convert.ToString));
                        _lines.Clear();

                    }
                }
            }

        }
    }

運行工人完成

private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            StopSplit();
            _filesMade.Clear();
            ProcessText.Text = "Split cancelled";
            return;
        }
        _filesMade.Clear();
        ProcessText.Text = "Split has completed, click here to open the directory";
    }

我敢打賭您的BgW是您班上的一員...
在Startsplit()中,每次執行此函數時都會添加一個新的回調。
這就是為什么它可以運行多次。

晚飯后的其他答案。

吃完晚飯...
您的計數方法有多種錯誤:
1)如果您缺少文件,我敢打賭這是最后一個文件。 例如30行,3個文件:
i % numberOfRows在i = i % numberOfRows處為零,但我未達到30。
2)您缺少行,例如31行4個文件:
文件保存在i = 7、14、21、28。第29-31行丟失。

我建議您使用嵌套的for循環,外部的用於文件,內部的用於行,並改善計算。 並將所有列表和計數器放入函數中!
希望您感謝我的回答。 我討厭在平板電腦上打字。 但也不想為此而啟動我的計算機... ;-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM