无法从已关闭的文本读取器读取

本文关键字:读取 文本 | 更新日期: 2023-09-27 18:37:06

我有一个处理一些大型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();
}

。引发以下异常

无法从已关闭的文本读取器读取。 ObjectDisposedException in mscorlib 方法: 无效阅读器已关闭()

堆栈跟踪: at System.IO.__Error.ReaderClosed() at System.IO.StreamReader.ReadLine() at CsvReader.PrepareReader(TextReader reader) in CsvReader.cs:line 93

任何建议都非常感谢。 另外,完成挑战的最佳方式是吗?

注释:框架 2.0

谢谢。

无法从已关闭的文本读取器读取

当你使用using (tmpReader)时,它会关闭tmpReader(它引用与reader相同的对象),所以当你尝试从循环中的reader读取时,它是关闭的。

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

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

    // 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 使用输入引用,并将读取器移动到所需的位置。

请注意在此方法之外关闭阅读器