簡體   English   中英

C#應用程序中的System.ArgumentOutOfRangeException

[英]System.ArgumentOutOfRangeException in C# Application

我已經實現了Cuong在這里建議的解決方案: C#處理固定寬度文件

我還讓它通過一個文件夾並將其應用於該文件夾中的所有.txt文件。

一切正常,但對於某些.txt文件,它在var csvLines上失敗,並出現以下錯誤:

{"Index and length must refer to a location within the string.\r\nParameter name: length"}

A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
System.ArgumentOutOfRangeException: Index and length must refer to a location within the string.
Parameter name: length
   at System.String.InternalSubStringWithChecks(Int32 startIndex, Int32 length, Boolean fAlwaysCopy)
   at System.String.Substring(Int32 startIndex, Int32 length)
   at FixedWidthFiles.Main.<>c__DisplayClass11.<>c__DisplayClass13.<buttonProcessAllFiles_Click>b__d(KeyValuePair`2 pair) in \\GBMACCMPFS11\Shhk$\Visual Studio 2010\Projects\FixedWidthFiles\FixedWidthFiles\Main.cs:line 138
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.String.Join(String separator, IEnumerable`1 values)
   at FixedWidthFiles.Main.<>c__DisplayClass11.<buttonProcessAllFiles_Click>b__c(String line) in \\GBMACCMPFS11\Shhk$\Visual Studio 2010\Projects\FixedWidthFiles\FixedWidthFiles\Main.cs:line 137
   at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
   at System.IO.File.InternalWriteAllLines(TextWriter writer, IEnumerable`1 contents)
   at System.IO.File.WriteAllLines(String path, IEnumerable`1 contents)
   at FixedWidthFiles.Main.buttonProcessAllFiles_Click(Object sender, EventArgs e) in \\GBMACCMPFS11\Shhk$\Visual Studio 2010\Projects\FixedWidthFiles\FixedWidthFiles\Main.cs:line 140

知道什么是錯的嗎? 它可能是文件,但我希望在代碼中可以糾正/改進某些內容:)


代碼是這樣的:

private void buttonProcessAllFiles_Click(object sender, EventArgs e)
{
    if (fileFolderPath == "")
    {
        MessageBox.Show("Load Folder First", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

    }
    else
    {
        int count = 0;
        //foreach (var file in Directory.GetFiles(fileFolderPath, "*.txt", SearchOption.AllDirectories))
        foreach (var file in Directory.GetFiles(fileFolderPath, "*.txt"))
        {
            count++;
            System.Diagnostics.Debug.WriteLine(count);
            fileFolderFull = Path.GetFullPath(file);
            System.Diagnostics.Debug.WriteLine(fileFolderFull);
            fileFolderName = Path.GetFileNameWithoutExtension(file);
            System.Diagnostics.Debug.WriteLine(fileFolderName);

            //MessageBox.Show("Full Folder: " + fileFolderFull);
            //MessageBox.Show("File Name: " + fileFolderName);

            var lines = File.ReadAllLines(fileFolderFull);

            var widthList = lines.First().GroupBy(c => c)
                                         .Select(g => g.Count())
                                         .ToList();

            var list = new List<KeyValuePair<int, int>>();

            int startIndex = 0;

            for (int i = 0; i < widthList.Count(); i++)
            {
                var pair = new KeyValuePair<int, int>(startIndex, widthList[i]);
                list.Add(pair);

                startIndex += widthList[i];
            }

            try
            {
                var csvLines = lines.Select(line => string.Join(",",
                                    list.Select(pair => line.Substring(pair.Key, pair.Value))));

                File.WriteAllLines(fileFolderPath + "\\" + fileFolderName + ".csv", csvLines);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex);
            } 
        }

        MessageBox.Show("File Saved", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

錯誤的行是這樣的:

var csvLines = lines.Select(line => string.Join(",",
                                        list.Select(pair => line.Substring(pair.Key, pair.Value))));

讀取堆棧跟蹤。 第一個有趣的位置是:

Visual Studio 2010\Projects\FixedWidthFiles\FixedWidthFiles\Main.cs:line 138

這是您的文件,包含您的代碼。 例外情況是,您正在讀取索引中的字符串,該索引大於字符串大小。 這都表示代碼中存在錯誤。 轉到該文件並分析該行。 一旦你想到這一點並且不知道為什么索引可能超出那個地方的范圍,復制那些代碼以及一些代碼,並在此處發布。 僅僅通過堆棧跟蹤很難說出更多信息。

編輯:你已經添加了代碼,很酷!

由於它在子字符串中肯定失敗,請查看子字符串作為索引的內容:它是來自pair的值。 該值來自列寬的增量求和,因此很可能您的一個輸入文件只有一行......太短。 檢查文件的開頭或結尾有虛假的空行!

你必須剝離這些行的文件,或者修改你的代碼:不是盲目地調用子串,而是使用if或Math.min來保護它:

str.Substring(
    Math.Min(str.Length, pair.Key), // here it MAY be needed a str.Length-1 instead!
    Math.Min(Math.Max(0,str.Length-pair.Key), pair.Value)
)

這樣,對於所有太短的線,場切割器將返回空字符串。 請注意,保護這兩個參數是很好的,並且值得檢查Length-StartIndex與負數,因為它們的StartIndex可能大於空行的長度:)

順便說一句。 通過StartIndex我當然意味着對.Key ..

我認為它在Substring方法上失敗了。 你能加一個line.Length>(pair.Key + pair.Value)的支票嗎?

暫無
暫無

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

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