FileHelpers icon indicating copy to clipboard operation
FileHelpers copied to clipboard

MultiRecordEngine. Stream is Closed after First Read

Open tarasbosyi opened this issue 3 years ago • 0 comments

        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
            }
        }

tarasbosyi avatar May 10 '22 08:05 tarasbosyi