PCL.Storage、OpenAsync() 未写入数据

PCL.Storage, OpenAsync() not writing data

我正在尝试将文件保存到缓存(在 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() 方法,但该方法非常简单,而且确实达到了我的预期。 ..

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

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

在您的情况下,data 流(作为参数提供)似乎已经位于基础数据的末尾,因此调用 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;
    }
}