Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP: async read file into byte[]

I want to read a locally stored file into a byte array. How do I do that? This is my try:

StorageFolder folder = await StorageFolder.GetFolderFromPathAsync(filePath);
var file = await folder.GetFileAsync(filePath);
var buffer = await FileIO.ReadBufferAsync(file);
DataReader dataReader = Windows.Storage.Streams.DataReader.FromBuffer(buffer);
// doesn't work because ReadBytes wants a byte[] as parameter and also isn't asynchronous
byte[] result = dataReader.ReadBytes(buffer.Length);
like image 924
testing Avatar asked Mar 18 '16 10:03

testing


3 Answers

I think the other answers make things unnecessarily complicated. There is a convenient extension method IBuffer.ToArray() for this purpose.

Simply do this:

using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Storage;
...
IStorageFile file;
IBuffer buffer = await FileIO.ReadBufferAsync(file);
byte[] bytes = buffer.ToArray();
like image 191
Daniel Rosenberg Avatar answered Sep 21 '22 09:09

Daniel Rosenberg


        StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        StorageFile sampleFile = await storageFolder.GetFileAsync(FILE_NAME);

        byte[] result;
        using (Stream stream = await sampleFile.OpenStreamForReadAsync())
        {
            using (var memoryStream = new MemoryStream())
            {

                stream.CopyTo(memoryStream);
                result = memoryStream.ToArray();
            }
        }
like image 45
matihuf Avatar answered Sep 20 '22 09:09

matihuf


Three concepts come to my mind - using FileStream and modyfing your method little:

  • the first reads bytes via a provided buffer, though this method needs seekable stream:

    FileOpenPicker picker = new FileOpenPicker();
    picker.FileTypeFilter.Add(".txt");
    using (Stream fileStr = await (await picker.PickSingleFileAsync()).OpenStreamForReadAsync())
    {
        byte[] bytes = new byte[fileStr.Length];
        const int BUFFER_SIZE = 1024;
        byte[] buffer = new byte[BUFFER_SIZE];
        int position = 0;
        int bytesread = 0;
        while ((bytesread = await fileStr.ReadAsync(buffer, 0, BUFFER_SIZE)) > 0)
           for (int i = 0; i < bytesread; i++, position++)
               bytes[position] = buffer[i];
    }
    
  • the second method asynchronously copies filestream to memory then gets it as an array:

    using (MemoryStream memStream = new MemoryStream())
    using (Stream fileStr = await (await picker.PickSingleFileAsync()).OpenStreamForReadAsync())
    {
        await fileStr.CopyToAsync(memStream);
        byte[] bytes = memStream.ToArray();
    }
    
  • your method with little mdification - processing via memory stream:

    var buffer = await FileIO.ReadBufferAsync(file);
    using (MemoryStream mstream = new MemoryStream())
    {
         await buffer.AsStream().CopyToAsync(mstream);
         byte[] result = mstream.ToArray();
    }
    

Or maybe better you can avoid using byte[] and instead use IBuffer or MemoryStream.

like image 41
Romasz Avatar answered Sep 17 '22 09:09

Romasz