无法从封闭的TextReader中读取

时间:2012-06-14 15:03:56

标签: c# .net-2.0

我有一个处理一些大型CSV文件的系统。

现在出现了这样的情况:这些文件可能在实际以逗号分隔的内容之前有许多无分隔且无价值的行。

我采取的方法是创建一个临时读取器,以确定多余行的数量,然后在准备好处理的那些行上移动工作的TextReader。

我的代码如下:

private static TextReader PrepareReader(TextReader reader)
    {
        // Variables
        TextReader tmpReader = reader;
        Int32 superfluousLineCount = 0;

        // Determine how many useless lines we have
        using (tmpReader)
        {
            string line;
            string headerIdentifier = "&1,";
            while ((line = tmpReader.ReadLine()) != null)
            {
                // Check if the line starts with the header row identifier
                if (line.Substring(0, 3) != headerIdentifier)
                {
                    // Increment the superfluous line counter
                    superfluousLineCount++;
                }
                else
                {
                    break;
                }
            }
        }

        // Move the source reader through how many lines we want to ignore
        using (reader)
        {
            for (int i = superfluousLineCount; i > 0; i--)
            {
                reader.ReadLine();
            }
        }

        // Return
        return reader;
    }

但是,代码的这一部分中的reader.ReadLine();

for (int i = superfluousLineCount; i > 0; i--)
{
reader.ReadLine();
}

...抛出以下异常

  

无法从已关闭的TextReader中读取。   mscorlib中的ObjectDisposedException   方法:     Void ReaderClosed()

     

堆栈跟踪:   在System.IO .__ Error.ReaderClosed()   在System.IO.StreamReader.ReadLine()   在CsvReader.cs中的CsvReader.PrepareReader(TextReader reader):第93行

任何建议都非常感谢。此外,是我应对挑战的最佳方式吗?

备注:Framework 2.0

感谢。

2 个答案:

答案 0 :(得分:7)

当您使用using (tmpReader)时,它会关闭tmpReader(它引用与reader相同的对象),因此当您尝试从循环中的reader读取时,它已关闭。

最好的办法是将两个循环结合起来。正弦你只想跳过线,我认为第一个循环的逻辑就足够了。

答案 1 :(得分:0)

我认为你只需要这样做(规范化/纠正它,我做了一些简化而没有任何编译或测试):

    // edit
    private static TextReader PrepareReader(TextReader reader, out string outLine)
    {



            string line;
            string headerIdentifier = "&1,";
            while ((line = reader.ReadLine()) != null)
            {
                // Check if the line starts with the header row identifier
                if (line.Substring(0, 3) != headerIdentifier)
                {
                    // ... do nothing
                }
                else
                {
                    // edit
                    outLine = line;
                    break;
                }
            }

    }

IOW使用输入参考,并将阅读器移动到您想要的位置。

请注意关闭您的读者以外的方法