3

I use this code to save an Stream to file

StorageFolder coverImageFolder = await StorageFolder.GetFolderFromPathAsync(AppInfo.LF_CoverFolder_Path);
string coverName = System.IO.Path.GetRandomFileName();

// Create an instance of ArchiveReader.
ArchiveReader reader = new ArchiveReader(pickedFile);

// Get a first image (stream) from archive.
using (var imageStream = await reader.GetFirstEntryStream()) { // IRandomAccessStream

// Save ImageStream to 'CoverImage' folder
StorageFile coverFile = await coverImageFolder.CreateFileAsync(coverName);

var coverStream = await coverFile.OpenAsync(FileAccessMode.ReadWrite); // IRandomAccessStream
using (var coverOutputStream = coverStream.AsStreamForWrite()) { // Stream
      using (var imageInputStream = imageStream.AsStreamForRead()) { // Stream
           await imageInputStream.CopyToAsync(coverOutputStream);
           await coverOutputStream.FlushAsync();
      }
}

It works as it should be. But, I want to know that is this a good or correct way to save .NET stream to file in Universal App?

Suttisak
  • 101
  • 2
  • 9
  • you should add this as suggestion on the uservoice site for universal apps. https://wpdev.uservoice.com/forums/110705-universal-windows-platform – Ken Tucker Oct 07 '15 at 16:09
  • 1
    The `FlushAsync` call is superfluous since you are going to dispose the resource anyway. I think in some cases it causes perf issues, too (full flush vs. sitting in write cache). Also the use of `AppInfo.LF_CoverFolder_Path` is suspicious (not necessarily wrong, but suspicious) since persisting static file paths can cause issues (eg if the user moves your app to another drive, or changes where they store files). – Peter Torr - MSFT Oct 08 '15 at 00:12

1 Answers1

1

If I understand correctly, you were trying to save the imageStream(IRandomAccessStream) to a coverFile(StrorageFile).

AsStreamForWrite and AsStreamForRead are both the Windows Runtime extension methods in .NET. In this case, you don’t need to convert Windows Runtime Stream to .NET IO stream (it will take some extra performance cost). I will suggest you using the way as following (without using .NET class library).

        var src = await KnownFolders
                        .PicturesLibrary
                        .GetFileAsync("210644575939381015.jpg")
                        .AsTask();

        var target = await KnownFolders
                        .PicturesLibrary
                        .CreateFileAsync("new_file.jpg")
                        .AsTask();


        using (var srcStream = await src.OpenAsync(FileAccessMode.Read))
        using (var targetStream = await target.OpenAsync(FileAccessMode.ReadWrite))
        using (var reader = new DataReader(srcStream.GetInputStreamAt(0)))
        {


            var output = targetStream.GetOutputStreamAt(0);

            await reader.LoadAsync((uint)srcStream.Size);

            while (reader.UnconsumedBufferLength > 0)
            {
                uint dataToRead = reader.UnconsumedBufferLength > 64
                                    ? 64
                                    : reader.UnconsumedBufferLength;

                IBuffer buffer = reader.ReadBuffer(dataToRead);

                await output.WriteAsync(buffer);
            }

            await output.FlushAsync();
        }
Jeffrey Chen
  • 4,650
  • 1
  • 18
  • 22