Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream.CopyTo not copying any stream data

I'm having an issue with copying data from a MemoryStream into a Stream inside a ZipArchive. The following is NOT working - it returns only 114 bytes:

GetDataAsByteArray(IDataSource dataSource)
{
    using (var zipStream = new MemoryStream())
    {
        using (var archive = new ZipArchive(zipStream, ZipArchiveMode.Create, true))
        {
            var file = archive.CreateEntry("compressed.file");
            using (var targetStream = file.Open())
            {
                using (var sourceStream = new MemoryStream())
                {
                    await dataSource.LoadIntoStream(sourceStream);
                    sourceStream.CopyTo(targetStream);
                }
            }
        }
        var result = zipStream.ToArray();
        zipStream.Close();
        return result;
    }
}

However, using the implementation below for the "copy"-process, all 1103 bytes are written to the array/memory stream:

await targetStream.WriteAsync(sourceStream.ToArray(), 0, (int) sourceStream.Length);

I'm wondering why the CopyTo yields less bytes. Also I'm feeling unsecure with the cast to Int32 in the second implementation.

FYI: Comparing the byte array: It looks like only the header and footer of the zip file were written by the first implementation.

like image 844
Herdo Avatar asked Aug 04 '14 15:08

Herdo


People also ask

What is the difference between MemoryStream and FileStream?

As the name suggests, a FileStream reads and writes to a file whereas a MemoryStream reads and writes to the memory. So it relates to where the stream is stored.

What is stream copy?

CopyTo(Stream) Reads the bytes from the current stream and writes them to another stream. Both streams positions are advanced by the number of bytes copied. CopyTo(Stream, Int32) Reads the bytes from the current stream and writes them to another stream, using a specified buffer size.

How does stream work in C#?

In C# file operations, normally streams are used to read and write to files. A stream is an additional layer created between an application and a file. The stream is used to ensure smooth read and write operations to the file. Streams are normally used when reading data from large files.


2 Answers

Stream.CopyTo() starts copying from the stream's current Position. Which probably isn't 0 after that LoadIntoStream() call. Since it is a MemoryStream, you can simply fix it like this:

    await dataSource.LoadIntoStream(sourceStream);
    sourceStream.Position = 0;
    sourceStream.CopyTo(targetStream);
like image 86
Hans Passant Avatar answered Oct 11 '22 02:10

Hans Passant


Set sourceStream.Position = 0 before copying it. The copy will copy from the current position to the end of the stream.

like image 24
Carl Avatar answered Oct 11 '22 01:10

Carl