locked
How to convert DeflateStream to InMemoryRandomAccessStream? RRS feed

  • Question

  • Hi,

    I want to read an item from ZipArchive into a InMemoryRandomAccessStream. The way I am doing is like below:

    using (var packageStream = await this.zipFile.OpenStreamForReadAsync())
                {
                    using (var archive = new ZipArchive(packageStream, ZipArchiveMode.Read))
                    {
                        var entry = archive.GetEntry(target);
    
                        if (entry != null)
                        {
                            using (var stream = entry.Open())
                            {   
                                this.ConvertToRandomAccessStream(stream, entry.Length);
                            }
                        }
                    }
                }
    Then,

    private async Task<IRandomAccessStream> ConvertToRandomAccessStream(Stream stream, long lengthToRead)
            {
                if (stream == null)
                {
                    throw new ArgumentNullException("stream");
                }
    
                var randomAccessStream = new InMemoryRandomAccessStream();
    
                using (var dataWriter = new DataWriter(randomAccessStream))
                {
                    while (true)
                    {
                        int length = lengthToRead > int.MaxValue ? int.MaxValue : (int)lengthToRead;
    
                        byte[] bytes = new byte[length];
                        int count = stream.Read(bytes, 0, bytes.Length);
                        if (count > 0)
                        {
                            byte[] bytesRead = new byte[count];
                            Array.Copy(bytes, 0, bytesRead, 0, count);
                            dataWriter.WriteBytes(bytesRead);
                        }
    
                        lengthToRead -= int.MaxValue;
    
                        if (lengthToRead <= 0)
                        {
                            break;
                        }
                    }
    
                    await dataWriter.StoreAsync();
                    dataWriter.DetachStream();
                }
    
                await randomAccessStream.FlushAsync();
                randomAccessStream.Seek(0);
    
                return randomAccessStream;
            }

    It works. But it is not efficient with hug stream. Do you know if there is a more efficient way of converting?

    Thanks,


    Fan

    Monday, September 23, 2013 11:15 PM

All replies

  • There's a good answer on StackOverflow about converting a Stream to an InMemoryRandomAccessStream:  http://stackoverflow.com/questions/7669311/is-there-a-way-to-convert-a-system-io-stream-to-a-windows-storage-streams-irando


    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Tuesday, September 24, 2013 1:24 PM
    Moderator
  • This I tried. But it didn't work. My codes was something like this:

    ...

    using (var stream = entry.Open()) { MemoryStream memoryStream = new MemoryStream(); await stream.CopyToAsync(memoryStream); randomAccessStream = memoryStream.AsRandomAccessStream(); randomAccessStream.Seek(0);

    }

    ...

    Streams seemed to be converted but the stream converted using CopyToAsync is somewhere different. Because when I am trying to read the last value from stream, I got exception of saying "The operation attempted to access data outside the valid range". This is the codes that read last value from stream:

                    var offsetSize = (uint)sizeof(UInt64);
                    Windows.Storage.Streams.Buffer offsetBuffer = new Windows.Storage.Streams.Buffer(offsetSize);
                    convertedStream.Seek(convertedStream.Size - (ulong)offsetSize);
    
                    await convertedStream.ReadAsync(offsetBuffer, offsetSize, InputStreamOptions.None);
    
                    var dataReader = DataReader.FromBuffer(offsetBuffer);
                    var offset = dataReader.ReadUInt64();
    
    Exception was thrown at the last line.


    Fan

    Tuesday, September 24, 2013 9:42 PM