PCL.Storage,OpenAsync()不写数据

时间:2017-07-26 10:23:28

标签: c# xamarin stream portable-class-library

我试图将文件保存到缓存中(在Xamarin.Android中)。调用以下方法时,输入变量包含所有正确的数据。它也完成没有错误,但当我去阅读文件时,它是空的(大小是正确的,但它包含所有0')。

public async Task<bool> SaveCache(Stream data, string id)
{
    try
    {
        //cache folder in local storage
        IFolder rootFolder = FileSystem.Current.LocalStorage;
        var folder = await rootFolder.CreateFolderAsync("Cache",
        CreationCollisionOption.OpenIfExists);
        //save cached data
        IFile file = await folder.CreateFileAsync(id + ".png", CreationCollisionOption.ReplaceExisting);
        byte[] buffer = new byte[data.Length];
        data.Read(buffer, 0, buffer.Length);
        using (Stream stream = await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite))
        {
            stream.Write(buffer, 0, buffer.Length);
        }
        return true;
    }
    catch
    {
        return false;
    }
}

我还从GitHub上的PCL.Storage库中读取了OpenAsync()方法,但该方法非常简单,并且它确实做了我期望它做的事情......

我做错了什么,或者你们有关于实际发生的事情的建议吗?

1 个答案:

答案 0 :(得分:0)

由于Stream.Read()方法始终从流的当前位置(see MSDN)开始读取,因此在尝试阅读任何内容之前,应确保您处于正确的位置。

在您的情况下,似乎data Stream(作为参数提供)已经位于基础数据的末尾,因此调用Stream.Read()基本上什么都不做。

要解决这个问题,您只需要在尝试读取流内容之前寻找流回到其数据的开头,例如使用Stream.Seek() method。所以你的固定代码可以看起来像这样:

public async Task<bool> SaveCache(Stream data, string id)
{
    try
    {
        //cache folder in local storage
        IFolder rootFolder = FileSystem.Current.LocalStorage;
        var folder = await rootFolder.CreateFolderAsync("Cache",
        CreationCollisionOption.OpenIfExists);

        //save cached data
        IFile file = await folder.CreateFileAsync(id + ".png", CreationCollisionOption.ReplaceExisting);
        byte[] buffer = new byte[data.Length];

        //make sure stream is at beginning of data, then read data into buffer
        data.Seek(0, SeekOrigin.Begin);
        data.Read(buffer, 0, buffer.Length);
        using (Stream stream = await file.OpenAsync(PCLStorage.FileAccess.ReadAndWrite))
        {
            stream.Write(buffer, 0, buffer.Length);
        }
        return true;
    }
    catch
    {
        return false;
    }
}