简体   繁体   中英

StreamReader.Read returns \0

I a newbie for coding. I am trying to read few characters at a time from a file, my code looks as follows. However, when the file has less than requested characters, it returns \\0 into the array, what does \\0 mean. Please help me understand.

using (StreamReader sr = new StreamReader(m_segmentFile.TempFileName))
using (StreamWriter sw = new StreamWriter(m_segmentFile.DisplayFile))
{
    while ( sr.Peek() >= 0 || m_segmentFile.ParserStatus == ParserStatus.Stopped)
    {
        buffer = new char[m_segmentFile.FieldWidth];
        sr.Read(buffer, 0, buffer.Length);
        block = new string(buffer);
        if (block[0] != '%')
        {
            noerrors = m_segmentFile.CheckBlockValidity(block) && noerrors;
            int percentComplete = (int)Math.Round((double)(offset * 100) / sr.BaseStream.Length);
            if (percentComplete > m_percentParsed && percentComplete <= 100)
            {
                m_percentParsed = (int)percentComplete;
                m_segmentFile.PercentParsed = m_percentParsed;
            }
            block = (m_segmentFile.FieldWidth * index).ToString() + ":" +block;
            sw.WriteLine(block);
            index++;
            m_parserStatus = ParserStatus.Parsing;
        }
        else
        {
            sw.WriteLine(block);
            //sr.BaseStream.Seek();
        }
    }

A value of 0 means end of file.

From the StreamReader.Read Method (Char[], Int32, Int32) documentation:

Return Value
Type: System.Int32
The number of characters that have been read, or 0 if at the end of the stream and no data was read. The number will be less than or equal to the count parameter, depending on whether the data is available within the stream.

A more correct way to read the characters from a file would be to only use the characters which were just read from the file using String Constructor (Char[], Int32, Int32) . This should remove your extra 0 character from your string and also prevent you from re-reading characters from buffer from previous reads.

int readLength = sr.Read(buffer, 0, buffer.Length);
block = new string(buffer, 0, readLength);

A better option would probably be to use StringReader to wrap your StreamReader .

\\0 is the string termination control character.
It indicates the end of a string - or in your case - the end of a file.

Because it looks like you are parseing a fixed width file structure it is very likely you are going to have segment alignment issues. If each block should be m_segmentFile.FieldWidth length every time you need to keep reading until you have filled the buffer.

using (StreamReader sr = new StreamReader(m_segmentFile.TempFileName))
using (StreamWriter sw = new StreamWriter(m_segmentFile.DisplayFile))
{
    //I bet money you meant to use && with != stopped not || with == stopped.
    while ( sr.Peek() >= 0 && m_segmentFile.ParserStatus != ParserStatus.Stopped)
    {
        buffer = new char[m_segmentFile.FieldWidth];
        int offset = 0;

        //Keeps reading till the buffer is totally full;
        while(offset < m_segmentFile.FieldWidth && sr.Peek() >= 0 && m_segmentFile.ParserStatus != ParserStatus.Stopped)
        {
            offset += sr.Read(buffer, offset, buffer.Length - offset);
        }


        //Reads in to the offset we got to, in case we ended early due to the stream ending or being signaled to stop.
        block = new string(buffer, 0, offset);
        if (block[0] != '%')
        {
            noerrors = m_segmentFile.CheckBlockValidity(block) && noerrors;
            int percentComplete = (int)Math.Round((double)(offset * 100) / sr.BaseStream.Length);
            if (percentComplete > m_percentParsed && percentComplete <= 100)
            {
                m_percentParsed = (int)percentComplete;
                m_segmentFile.PercentParsed = m_percentParsed;
            }
            block = (m_segmentFile.FieldWidth * index).ToString() + ":" +block;
            sw.WriteLine(block);
            index++;
            m_parserStatus = ParserStatus.Parsing;
        }
        else
        {
            sw.WriteLine(block);
            //sr.BaseStream.Seek();
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM