2015-10-13 2 views
2

У меня есть метод Validate(Stream inputStream). Этот метод вызывает несколько других методов проверки, передавая inputStream каждому из них. Каждый из них создает новый TextFieldParser и считывает/проверяет файл.TextFieldParser Не задает поле EndOfData

Когда вызывается первый ValidateA(inputStream), он работает. Но, когда вызывается второй ValidateB(inputStream), parser.EndOfData равен true, поэтому он не читает поля.

Я попытался очистить код до его простейшей формы.

public int Validate(Stream inputStream, ref List<string> errors) 
{ 
    inputStream.Seek(0, SeekOrigin.Begin); 
    errors.AddRange(ValidateA(inputStream)); 

    // The 2nd time, the EndOfData is true, so it doesn't read the fields 
    inputStream.Seek(0, SeekOrigin.Begin); 
    errors.AddRange(ValidateB(inputStream)); 
... 
} 

private List<string> ValidateA(Stream inputStream) 
{ 
    List<string> errors = new List<string>(); 
    // Works fine the first time 
    using (var parser = new TextFieldParser(inputStream)) 
    { 
     parser.TextFieldType = FieldType.Delimited; 
     parser.SetDelimiters(","); 
     parser.TrimWhiteSpace = true; 
     int lineNumber = 0; 

     while (!parser.EndOfData) 
     { 
      string[] fields = parser.ReadFields(); 
      // Processing.... 
     } 

     if (lineNumber < 2) 
      errors.Add(string.Format("There is no data in the file")); 
    } 
    return errors; 
} 

Здесь возникает проблема. Метод ValidateB не может обработать файл, потому что поле EndOfData не получает сброс.

private List<string> ValidateB(Stream inputStream) 
{ 
    List<string> errors = new List<string>(); 
    using (var parser = new TextFieldParser(inputStream)) 
    { 
     parser.TextFieldType = FieldType.Delimited; 
     parser.SetDelimiters(","); 
     parser.TrimWhiteSpace = true; 
     int LineNumber = 0; 
     while (!parser.EndOfData) 
     { 
      // Processing.... 
     } 
    } 

    return errors; 
}  
+0

Я также попытался скопировать входной поток в новый поток, чтобы проверить, не сработает ли он. –

+0

Значит, вы знаете, что Seek() фактически не реализован в * конкретном классе, который наследует от Stream. Как бы то ни было, отладчик говорит вам. Там где-то есть программист, который заслуживает от вас отвращения за то, что он не бросает InvalidOperationException, мы не можем помочь вам найти его. –

ответ

2

Комментарий от @HansPassant является правильным и приведет меня к изменению способа передачи данных. Вместо того, чтобы проходить Stream вокруг, я преобразовал MemoryStream в byte[].

Тогда, в методе ValidateX(byte[] fileByteArray), я бы создал новый MemoryStream из массива байтов и использовал его.

Пример:

Stream stream = model.PostedFile.InputStream; 
MemoryStream memStream = new MemoryStream(); 
stream.CopyTo(memStream); 
byte[] data = memStream.ToArray(); 
var result = ValidateB(data); 

А потом,

private List<string> ValidateB(byte[] fileByteArray) 
{ 
    List<string> errors = new List<string>(); 
    MemoryStream ms = new MemoryStream(fileByteArray); 
    ms.Position = 0; 
    ms.Seek(0, SeekOrigin.Begin); 
    using (var parser = new TextFieldParser(ms)) 
    { 
     // Processing... 
    } 

} 

Это предотвратило проблемы с EndOfData и пытается получить доступ к потоку, который был закрыт.

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