private static async void SetImage(PlaylistItem song,string source,string imageName) { HttpClient client = new HttpClient(); HttpResponseMessage message = await client.GetAsync(source); StorageFolder myfolder = Windows.Storage.ApplicationData.Current.LocalFolder; StorageFile sampleFile = await myfolder.CreateFileAsync(imageName,CreationCollisionOption.ReplaceExisting); byte[] byteArrayFile = await message.Content.ReadAsByteArrayAsync(); await FileIO.WriteBytesAsync(sampleFile,byteArrayFile); song.Image = new BitmapImage(new Uri(sampleFile.Path)); }
解决方法
大多数存储服务(Azure Blob存储,Amazon S3,CloudFiles)实际上使用文件的MD5或SHA哈希作为其ETag,该值用于检测文件的更改以进行缓存和并发.通常,对文件的HEAD操作将返回其标头和ETag值.
如果您可以选择自己的算法,请选择SHA256或更高版本,因为这些算法经过高度优化,其大块大小意味着计算大文件的哈希值要快得多. SHA256实际上比旧的MD5算法快得多.
你使用什么存储服务?
编辑
如果您只想检查文件以避免再次下载,可以直接使用ETag. ETag就是为了这个目的而创建的.第一次下载时,您只需将其与文件一起存储即可.这就是代理和缓存如何知道向您发送图片的缓存版本而不是命中目标服务器.
实际上,您可以使用ETag / If-None-Match标头对文件执行GET操作.如果目标文件未更改,则中间代理和最终Web服务器将返回304状态代码.这样可以减少下载列表中所有图像所需的请求数.
另一种方法是存储文件的Last-Modified标头值,并在GET中使用If-Modified-Since标头
编辑2
HttpResponseMessage具有多个Headers属性,包括on the message itself和Content.您需要使用适当的属性来检索ETag值.
您还可以使用Fiddler检查以确保服务器确实返回ETag.
编辑3
终于找到了从Youtube获得ETag的方法!答案来自“How to get thumbnail of YouTube video link using YouTube API?”
在ytimg.com上对YouTube缩略图进行HEAD或GET时,不会返回ETag或Last-Modified标头.
另一方面,使用YouTube的Data API并在gdata.youtube.com上进行GET,可以返回有关视频的大量信息.包含ETag值,但我怀疑它会在视频发生变化时发生变化.这可能没问题,如果您只想在视频更改时下载图像,或者您不想再次下载图像.
我使用的代码是:
var url = "http://gdata.youtube.com/Feeds/api/videos/npvJ9FTgZbM?v=2&prettyprint=true&alt=json"; using(var client = new HttpClient()) { var response = await client.GetAsync(url); var etag1 = response.Headers.ETag; var content = await response.Content.ReadAsStringAsync(); ... }