CSV重新格式化程序中的System.IndexOutOfRangeException

时间:2013-05-29 23:13:46

标签: c# debugging csv file-io

我正在开发一个使用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).

4 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

读取分隔的文本文件并不像第一次出现那么简单。

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

  1. 您在文件中有一条简短的记录。
  2. 您有一个记录,其中一个字段包含嵌入的CR,LF或CR + LF对,从而将记录拆分为两个(或更多)行,从而导致上面的情况#1。
  3. 你可能会比你想象的更多列。造成这种情况的主要原因是数据被污染了世界的杂质,实际上是不洁净的。人们已经知道用分隔符字符(例如逗号或分号)来丢弃数据。当你在文本上做一个天真的Split()时,你并不总能得到你想要的东西。对于“CSV”文件尤其如此,格式相当于[cough] 松散定义。甚至更松散地实施。

    你可能想看一下使用来自Fast CSV Reader的Sebastien Lorion的CodeProject。它运作良好,可以处理很多你可能会遇到的意外情况。

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

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

答案 3 :(得分:0)

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

我可能会添加的另一件事是,看起来你正在获取一个数组,将其转换为IEnumerable,然后将其转换回数组而不使用IEnumerable提供的任何花哨的东西。我建议使用foreach循环代替这个任务。

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