Khaled
Khaled

Reputation: 59

Reading the content of the stream "Stream" using "ReadToEnd()" in C#

I have a function which has an input parameter of type "stream". I want to read the content of this stream and compare to a content of a file. The following has been done:

public bool func(Stream stream, string tempFilePath, string dstFilePath)
{
    string[] File1 = File.ReadAllLines(tempFilePath);
    stream.Seek(0, SeekOrigin.Begin); 
    int line = 0;
    StreamReader reader = new StreamReader(stream);
    string[] File2 = reader.ReadToEnd().Split(
        new[] { "\r\n", "\r", "\n" }, 
        StringSplitOptions.None                                                                        
    );

    while (line < File1.Length)
    {
        if (astFile2[line] != astFile1[line])
            break;

        line++;
    }

    bool ret = line == astFile1.Length && line == astFile2.Length - 1;
    if (ret )
    {
        using (var dstFile = new FileStream(dstFilePath, FileMode.Create, FileAccess.Write))
        {
            stream.Seek(0, SeekOrigin.Begin); 
            stream.CopyTo(dstFile );
        }
    }

    return ret;
}

The problem is that I can't take the content of the variable "stream" anymore using the command: "stream.CopyTo(dstFile ); " The content is empty!

The "position" of the stream using the stream.Seek(0, SeekOrigin.Begin); is correct. I have used the stream.Seek(0, SeekOrigin.Begin); command after the ReadToEnd() line, but it did not help. I have used also the stream.Position = 0, and did not help too. That why I think there should be no problem by position.

What is it missed in this code? Why the ReadToEnd() command results in emptying the stream?

For test, I also did the following:

  string[] File2 = reader.ReadToEnd().Split(
                                            new[] { "\r\n", "\r", "\n" },
                                            StringSplitOptions.None
                                        );


  stream.Position = 0;
   string[] File3 = reader.ReadToEnd().Split(
                                            new[] { "\r\n", "\r", "\n" },
                                            StringSplitOptions.None
                                        );

The content of "File3" is still empty!

Upvotes: 0

Views: 1165

Answers (2)

Matthew Watson
Matthew Watson

Reputation: 109802

It seems that you are not showing us the actual faulty code.

I have paraphrased your code to a compilable console app, which does NOT reproduce the problem:

using System.IO;

namespace Demo
{
    public static class Program
    {
        static void Main()
        {
            string sourceFile = @"D:\tmp\source.txt";
            string destFile   = @"D:\tmp\dest.txt";

            MemoryStream ms = new MemoryStream();

            var data = File.ReadAllBytes(sourceFile);
            ms.Write(data, 0, data.Length);
            ms.Position = 0;

            func(ms, sourceFile, destFile);
        }

        public static void func(Stream stream, string tempFilePath, string dstFilePath)
        {
            File.ReadAllLines(tempFilePath);
            stream.Seek(0, SeekOrigin.Begin);

            var reader = new StreamReader(stream);
            reader.ReadToEnd();
            stream.Position = 0;

            using (var dstFile = new FileStream(dstFilePath, FileMode.Create, FileAccess.Write))
            {
                stream.CopyTo(dstFile);
            }
        }
    }
}

So I'm afraid that the answer to the question "what is missed in this code?" is "a reproducable problem".

It is crucial that you tell us the concrete type of the Stream that you are passing to func(). It is likely that is the cause of your problem - for example, it's a stream that can only be read once (although in that case, trying to change the stream position should really throw an UnsupportedOperationException).

Upvotes: 2

Barracoder
Barracoder

Reputation: 3764

I always make sure I call stream.Flush() before doing a ReadToEnd().

Upvotes: 0

Related Questions