FileHelpers
FileHelpers copied to clipboard
MultiRecordEngine. Stream is Closed after First Read
public void BeginReadStream(TextReader reader)
{
BeginReadStream(new NewLineDelimitedRecordReader(reader));
}
internal sealed class NewLineDelimitedRecordReader : IRecordReader
{
private readonly TextReader mReader;
/// <summary>
/// Read a file line by line from the specified textreader
/// </summary>
/// <param name="reader">TextReader to read and process</param>
public NewLineDelimitedRecordReader(TextReader reader)
{
mReader = reader;
}
/// <summary>
/// Read a record from the file
/// </summary>
/// <returns>unprocessed record</returns>
public string ReadRecordString()
{
return mReader.ReadLine();
}
/// <summary>
/// Close the reader
/// </summary>
public void Close()
{
mReader.Close();
}
}
private void ReadNextRecord()
{
string currentLine = mAsyncReader.ReadNextLine();
mLineNumber++;
bool byPass = false;
mLastRecord = null;
var line = new LineInfo(currentLine)
{
mReader = mAsyncReader
};
while (true)
{
if (currentLine != null)
{
try
{
mTotalRecords++;
Type currType = mRecordSelector(this, currentLine);
line.ReLoad(currentLine);
if (currType != null)
{
mRecordInfoTable.TryGetValue(currType, out IRecordInfo info);
if (info == null)
{
throw new BadUsageException("A record is of type '" + currType.Name +
"' which this engine is not configured to handle. Try adding this type to the constructor.");
}
mLastRecord = ReadRecord(info, LineNumber, line);
if (mLastRecord != null)
{
byPass = true;
return;
}
}
}
catch (Exception ex)
{
switch (mErrorManager.ErrorMode)
{
case ErrorMode.ThrowException:
byPass = true;
throw;
case ErrorMode.IgnoreAndContinue:
break;
case ErrorMode.SaveAndContinue:
var err = new ErrorInfo
{
mLineNumber = mAsyncReader.LineNumber,
mExceptionInfo = ex,
mRecordString = currentLine,
mRecordTypeName = RecordInfo.RecordType.Name
};
mErrorManager.AddError(err);
break;
}
}
finally
{
if (byPass == false)
{
currentLine = mAsyncReader.ReadNextLine();
mLineNumber = mAsyncReader.LineNumber;
}
}
}
else
{
mLastRecord = null;
if (RecordInfo.IgnoreLast > 0)
mFooterText = mAsyncReader.RemainingText;
try
{
mAsyncReader.Close();
}
catch { }
return;
}
}
}
If you try to Read From Stream, TextReader is closed and stream as well, just because ReadNextRecord method close TextReader and stream as well, and it is not possible to use this stream in the future.
public void ReadFromStream(Stream stream, MultiRecordEngine engine)
{
TextReader streamReader = new StreamReader(stream);
engine.BeginReadStream(streamReader);
while (engine.ReadNext() != null)
{
//something
}
}