【问题标题】:Downloading image from url doesn't always save the entire image (Winrt)从 url 下载图像并不总是保存整个图像 (Winrt)
【发布时间】:2013-08-01 11:43:03
【问题描述】:

我正在使用以下代码从 url 下载图像

HttpClient client = new HttpClient();
        var stream = await client.GetStreamAsync(new Uri("<your url>"));
        var file = await KnownFolders.PictureLibrary.CreateFileAsync("myfile.png");
        using (var targetStream = await file.OpenAsync(FileAccessMode.ReadWrite))
        {
            using (stream)
                await stream.CopyToAsync(targetStream.AsStreamForWrite());
        }

一些用户报告说它并不总是下载整个图像。他们有时会得到部分图像,其余的只是垃圾。

这有什么原因吗? 谢谢!

【问题讨论】:

  • 是否需要刷新/关闭/处置目标流/文件?
  • 我不确定。我认为 using 块会为我解决这个问题。但我会试一试。不幸的是,我无法重现该问题,因此我输入的任何“修复”都将是盲目的。刚刚意识到流不在 using 块中
  • @Javalsu 文档对从 Client.GetStreamAsync 返回的流上的 Dispose 方法有何评论。有些流需要刷新,有些则不需要
  • 我猜是因为你正在调用GetStreamAsync()............你需要进行同步调用stackoverflow.com/questions/26958829/…

标签: c# .net windows-runtime


【解决方案1】:

我建议尝试使用 DownloadData 或 DownloadDataAsync 方法的 WebClient 类。

File.WriteAllBytes("myfile.png",
    new WebClient().DownloadData("<your url>"));

edit 如果流给您带来麻烦,您可以改用字节数组响应。您的带有异步代码的“使用”语句可能会导致它提前处理,也许?

var httpClient = new HttpClient();
var data = await httpClient.GetByteArrayAsync(new Uri("<Your URI>"));
var file = await KnownFolders.PictureLibrary.CreateFileAsync("myfile.png");
var targetStream = await file.OpenAsync(FileAccessMode.ReadWrite)
await targetStream.AsStreamForWrite().WriteAsync(data, 0, data.Length);
targetStream.FlushAsync().Wait();
targetStream.Close();

【讨论】:

  • 感谢您的建议,但我不相信这在 Winrrt 中有效。
  • @Javalsu - 我认为问题可能在于“使用”语句过早地处理对象或 HttpClient 的流/完成问题。我编辑了我的答案,为您反映一个“可能”更稳定的解决方案。
【解决方案2】:

BackgroundDownloader 是下载文件的最简单方法。

using Windows.Storage;

public async Task DownloadPhoto(Uri uri)
{
    var folder = ApplicationData.Current.LocalFolder;
    var photoFile = await folder.CreateFileAsync("photo.jpg", CreationCollisionOption.ReplaceExisting);
    var downloader = new Windows.Networking.BackgroundTransfer.BackgroundDownloader();
    var dl = downloader.CreateDownload(uri, photoFile);
    await dl.StartAsync();
}

【讨论】:

  • 感谢您的建议,不幸的是我已经尝试过这种方法,但对我来说并不奏效。我的应用程序有很多在后台运行的进程,看来此方法必须等待所有其他进程结束才能启动。所以我无法使用它。
  • 即使在 StartAsync() 处等待并在下载函数处等待?
  • 是的,这很令人困惑,它会到达等待线并且永远不会进展。我开始在 microsoft 论坛上进行讨论,并达成共识,即我有其他进程阻止它启动。我无法确认这是真正的原因,但没有任何建议可以让它发挥作用。
  • 是的,它也发生在我身上:/ 那是我在同步方法中使用异步方法的时候。就像使用 .Result 调用等待函数一样。我解决了仅使用异步的问题...
  • 感谢您的提示,我会调查的。
【解决方案3】:

如果您使用 HttpClient,那么如果您的图像大于 64K,则会出错。您必须将 httpClient.MaxResponseContentBufferSize 设置为更大的值。

请参阅 MSDN 快速入门,他们将最大缓冲区大小设置为 256K。 http://msdn.microsoft.com/en-us/library/windows/apps/xaml/JJ152726(v=win.10).aspx

不过,我个人使用的是 BackgroundDownloader。

【讨论】:

    猜你喜欢
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多