2012-06-14 5 views
0

У меня есть система, обрабатывающая некоторые большие CSV-файлы.Не удается прочитать из закрытого TextReader

Теперь возник сценарий, в котором у этих файлов может быть несколько ничетуемых, бесполезных строк, предшествующих фактическому содержимому с разделителями-запятыми.

Подход, который я принял, заключается в создании временного считывателя для определения количества лишних строк, а затем перемещения рабочего 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. ObjectDisposedException в mscorlib Метод: Пустота ReaderClosed()

Трассировка стека: на System.IO .__ Error.ReaderClosed() на System.IO.StreamReader.ReadLine() на CsvReader.PrepareReader (ЧтениеТекста считыватель) в CsvReader.cs: строка 93

Любые советы, которые очень ценят. Кроме того, это лучший способ решить мою задачу?

Примечания: Рама 2.0

Спасибо.

ответ

7

При использовании using (tmpReader) он закроет tmpReader (который ссылается на тот же объект, как reader делает), поэтому при попытке чтения из reader в цикле, она закрыта.

Ваш лучший выбор - объединить две петли. Синус, вы хотите только пропустить строки, я думаю, что логика первого цикла достаточна.

+1

Right. Эта строка 'TextReader tmpReader = reader'' совершенно бессмысленна. –

+0

Спасибо, что имеет прекрасный смысл, теперь это было указано. Есть ли способ * скопировать * TextReader без повторного опроса файла? – Ste

+0

Отправлено [this SO thread] (http://stackoverflow.com/questions/831417/how-do-you-reset-ac-sharp-net-textreader-cursor-back-to-the-start-point) для что вы могли бы попробовать – Attila

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 использовать ссылку ввода, и переместить читатель, где вы хотите ,

Имейте в виду, чтобы закрыть ваш читатель вне этого метода

+0

Но с этим, разве я не пропустил первую строчку, которую захочу обработать? – Ste

+0

посмотреть в комментарии для редактирования op –

Смежные вопросы