【问题标题】:System.IndexOutOfRangeException in a CSV Reformatting ProgramCSV 重新格式化程序中的 System.IndexOutOfRangeException
【发布时间】:2013-05-29 23:13:45
【问题描述】:

我正在开发一个使用 C# 重新格式化 CSV 文件的程序。它导入 CSV 并使用某些列在新的 CSV 文件中表示。使用此代码时,我得到了 System.IndexOutOfRangeException 异常。

using System;
using System.Collections;
using System.Linq;

class CSVFiles
{
    static void Main(string[] args)
    {
        // Create the IEnumerable data source 
        string[] lines = System.IO.File.ReadAllLines(@"presta.csv");

        // Create the query. Put field 2 first, then 
        // reverse and combine fields 0 and 1 from the old field
        IEnumerable query =
            from line in lines
            let x = line.Split(';')
            select x[0] + ", base, 0, " + x[0] + ", " + x[7] + ", " + x[1] + ", " + x[2] + ", " + x[3] + ", " + x[15] + ", " + x[4] + ", " + x[6] + ", " + x[7] + ", Sí, " + x[12] + ", " + x[12] + ", " + x[12] + ", " + x[12];

        // Execute the query and write out the new file. Note that WriteAllLines 
        // takes a string[], so ToArray is called on the query.
        System.IO.File.WriteAllLines(@"outlet.csv", query.Cast<String>().ToArray());

        Console.WriteLine("outlet.csv written to disk. Press any key to exit");
        Console.ReadKey();
    }
}

导入的 CSV 有 16 列,所以它应该被索引到 x[17]。谁可以帮我这个事?或者也许还有另一种更好的方法?

这是整个调试输出:

'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.HostingProcess.Utilities.Sync\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.HostingProcess.Utilities.Sync.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\assembly\GAC_MSIL\Microsoft.VisualStudio.Debugger.Runtime\11.0.0.0__b03f5f7f11d50a3a\Microsoft.VisualStudio.Debugger.Runtime.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'c:\users\daniel\documents\visual studio 2012\Projects\CSVConverter\CSVConverter\bin\Debug\CSVConverter.vshost.exe'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml.Linq\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.Linq.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Data.DataSetExtensions\v4.0_4.0.0.0__b77a5c561934e089\System.Data.DataSetExtensions.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.CSharp\v4.0_4.0.0.0__b03f5f7f11d50a3a\Microsoft.CSharp.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\System.Data\v4.0_4.0.0.0__b77a5c561934e089\System.Data.dll'
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll'
The thread 'vshost.NotifyLoad' (0x52c) has exited with code 0 (0x0).
The thread 'vshost.LoadReference' (0x6cc) has exited with code 0 (0x0).
'CSVConverter.vshost.exe' (Managed (v4.0.30319)): Loaded 'c:\users\daniel\documents\visual studio 2012\Projects\CSVConverter\CSVConverter\bin\Debug\CSVConverter.exe', Symbols loaded.
A first chance exception of type 'System.IndexOutOfRangeException' occurred in CSVConverter.exe
An unhandled exception of type 'System.IndexOutOfRangeException' occurred in CSVConverter.exe
Additional information: Index was outside the bounds of the array.
The program '[6952] CSVConverter.vshost.exe: Managed (v4.0.30319)' has exited with code -1073741510 (0xc000013a).

【问题讨论】:

  • 你能给我们看看 CSV 吗?

标签: c# debugging csv file-io


【解决方案1】:

您说“导入的 CSV 有 16 列,因此应将其索引到 x[17]。”那是错的。数组索引为 0,因此如果 CSV 有 16 列 x[15] 将是最后一列。任何大于该值的索引都会给出越界异常。

编辑:查看您的代码,我注意到您实际上并没有尝试访问最终索引之外的任何内容,因此第一个问题可能与您的崩溃无关;这是另一个建议。添加一些边界检查。我会假设您的 LINQ 查询中的 Split 正在拆分一个不完整的行,然后您尝试访问不存在的索引(即该行上只有 4 个项目,应该被忽略,但您的代码只是假设它有 16 并尝试访问错误行中超出范围的索引)。如果您拆分一行并要访问 0 和 n 之间的索引,请在执行此操作之前检查以确保数组长度大于 n。

【讨论】:

    【解决方案2】:

    读取分隔文本文件并不像最初看起来那么简单。

    如果您的以分号分隔的文件有 16 列,则拆分行得到的数组应该的长度为 16(意味着数组中的最高偏移量为 +15)。如果源数据中的任何行满足以下任一条件,则它可能会更少:

    1. 您的文件中有一条简短的记录。
    2. 您有一条记录,其中一个字段包含嵌入的 CR、LF 或 CR+LF 对,因此将记录分成两行(或多行)并导致上述情况 #1。

    您最终可能会得到比您想象的更多的列。造成这种情况的主要原因是,被世界杂质污染的数据通常是不干净的。人们已经知道使用分隔符(例如逗号或分号)乱扔数据。当你在文本上做一个幼稚的Split() 时,你并不总是得到你想要的。对于“CSV”文件尤其如此,其格式定义相当 [cough] 松散。甚至更松散地实现。

    您可能想看看使用来自 CodeProject 的 Sebastien Lorion 的 Fast CSV Reader 来实现此目的。它工作得很好,可以处理很多你可能遇到的……意想不到的情况。

    您可能想查看的其他参考资料:

    编辑说明:国会图书馆似乎也考虑了 CSV 格式:http://www.digitalpreservation.gov/formats/fdd/fdd000323.shtml

    【讨论】:

    • 谢谢,尤其是快速 CSV 阅读器链接。另一个人提到了FileHelper 库,到目前为止它非常有用,而且容易得多。不幸的是,那个人删除了他的答案。但如果 filehelper 不起作用,我会尝试使用 Fast CSV Reader。
    【解决方案3】:

    您可能有一个额外的换行符(尤其是在文件末尾),它给出了一个空白字符串。要解决此问题,您可以将 where 条件修改为:

    from line in lines
    where !String.IsNullOrEmpty(line)
    ...
    

    【讨论】:

      【解决方案4】:

      我不确定我是否理解,但我会尽力而为。如果数组中有 16 项,那么数组中最后一项的索引将是 x[15],因为大多数语言中的数组从 0 而不是 1 开始计数。数组中第一项的索引是 x[ 0]。

      我可能要补充的另一件事是,看起来您正在获取一个数组,将其转换为 IEnumerable,然后将其转换回数组,而无需使用 IEnumerable 提供的任何花哨的东西。我建议改为使用 foreach 循环来执行此任务。

      祝你好运,希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2020-10-28
        • 2015-12-07
        • 1970-01-01
        • 2016-01-16
        • 1970-01-01
        • 2018-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多