TextFieldParser 未设置 EndOfData 字段
TextFieldParser Not Setting EndOfData field
我有一个Validate(Stream inputStream)
方法。此方法通过将 inputStream 传递给每个方法来调用其他几种验证方法。其中每一个都会创建一个新的 TextFieldParser
和 reads/validates 文件。
当调用第一个 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;
}
@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
出现问题并尝试访问已关闭的流。
我有一个Validate(Stream inputStream)
方法。此方法通过将 inputStream 传递给每个方法来调用其他几种验证方法。其中每一个都会创建一个新的 TextFieldParser
和 reads/validates 文件。
当调用第一个 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;
}
@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
出现问题并尝试访问已关闭的流。