2013-08-08 12 views
7

ここに私のシナリオです - 私はWindowsストアのアプリケーションがあります。私はローカルファイルと、インターネット上のファイルへのリンクを持っています。これらの2つのファイルが同じであるかどうかを確認する手段はありますか?なしリンクからファイルをダウンロードしますか?2つのファイルがインターネット上で同じであるかどうか比較してください

ファイルを取得するために使用されるコードはこれです:直接

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)); 

} 
+0

どのストレージサービスを使用していますか?ほとんどのサービスは並行処理の目的でハッシュを使用しますが、それらを取得する方法は異なる場合があります –

+0

問題のファイルはyoutubeビデオのサムネイルです –

+0

[2つのファイルが同じかどうかを判断する最も良い方法は?](http://stackoverflow.com/questions/714574/best-way-to-tell-if-two-files-that-same)を使用して、また、あなたの質問は、あなたが問題を理解していることを示していないオンライナーです(ファイルを比較する方法を研究したのはなぜですか? – CodeCaster

答えて

7

あなたのローカルファイルの。チェックサムは、衝突の可能性が非常に高い(つまり、同じチェックサムを持つ異なるファイル)ため、この操作には適していません。

ほとんどのストレージサービス(Azure Blobストレージ、Amazon S3、CloudFiles)は、実際にファイルのMD5またはSHAハッシュをETagとして使用します。この値は、キャッシュおよび同時実行の目的でファイルへの変更を検出するために使用されます。通常、ファイルのHEAD操作は、ヘッダーとETag値を返します。

独自のアルゴリズムを選択するオプションがある場合は、これらのアルゴリズムが高度に最適化されているため、大きなファイルサイズの計算ハッシュがはるかに高速であるため、SHA256以上を選択してください。 SHA256は、実際には古いMD5アルゴリズムよりもはるかに高速です。

どのストレージサービスを使用していますか?

EDIT

あなただけそれらを再度ダウンロードを避けるために、ファイルをチェックしたい場合は、直接のETagを使用することができます。 ETagはこの目的のために作られました。初めてダウンロードするときにファイルと一緒に保存するだけです。これは、プロキシとキャッシュが、宛先サーバーにヒットするのではなく、キャッシュされたバージョンの画像を送信する方法を知っています。

実際には、ETag/If-None-Matchヘッダーを使用してファイルに対してGETを実行するだけです。宛先ファイルが変更されていない場合、中間プロキシと最終Webサーバーは304ステータスコードを返します。これにより、リスト内のすべてのイメージをダウンロードするために必要なリクエスト数が半分になります。

代替は、ファイルのためのLast-Modifiedヘッダの値を格納し、あなたはETagヘッダがnullであることを言及GET

EDIT 2

に場合 - 変更-Sinceヘッダを使用することで、あなたのコードはあなたの検索方法を示していません。

HttpResponseMessageには複数のヘッダープロパティ(on the message itselfとそのContent)があります。適切なプロパティを使用してETag値を取得する必要があります。

また、Fiddlerを使用してサーバーが実際にETagを返すことを確認することもできます。

EDIT 3

が最後にYouTubeのからのETagを取得する方法を発見しました!答えは "How to get thumbnail of YouTube video link using YouTube API?"

ytimg.comからYouTubeサムネイルでHEADまたはGETを実行しても、ETagまたはLast-Modifiedヘッダーは返されません。

一方、YouTubeのデータ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(); 
    ... 
} 
+0

なし、アイデアは、ユーザーがインターネット上の画像のリストを閲覧していることです(リストは私のものではなく、それらが保管されている場所でもありません)、帯域幅の使用を制限したい、つまりユーザーが既にこの画像を持っている場合、それをダウンロードせずに、ローカルストレージからロードするだけです。 問題の画像はYouTube動画のサムネイルです。 –

+0

これは簡単な場合があります。 If-XXXヘッダーでHTTP GETを使用すると、ファイルが変更された場合にのみ取得することができます –

+0

アドバイスは良いですが、私の返答にnull ETagがあります:/ –

0

?いいえ、オンラインのファイルにもハッシュが付いている場合は、ファイルの平等性を正常にチェックする可能性が高くなります。

1

gitのようにファイルの内容のハッシュを計算することができます。 MD5などを使用してください。次に、ファイルが同じハッシュを持っているかどうかを確認するだけです。

+0

オンラインファイルに既に関連するチェックサムがある場合を除き、オペレータはチェックを実行するためにファイルをダウンロードする必要があります。 – ZombieSheep

+0

ほとんどのストレージサービスは、すでにこの目的でハッシュ(チェックサムではありません)を使用しています。通常、ファイルのETag値として格納されます。 –

+0

長さとハッシュは、通常は同じ呼び出しによって返されたヘッダーです。 –

1

をダウンロードしないで比較したい場合はとあなたはインターネット上でファイルを配置した人です。理想的にはファイルのチェックサムをアップロードする必要があります。新しいファイルをアップロードする前に、ローカルファイルのチェックサムとサーバーのチェックサムを確認してください。同じでない場合はアップロードを続行し、それ以外の場合はキャンセルします。

-2

ここに小さなヘルプがあります。まったく同じファイルについて、あなたは今、あなたは今、あなたがそれを比較することができ、ファイルのハッシュコードを計算した

public static string CalcHashCode(string filename) 
    { 
     FileStream stream = new FileStream(
      filename, 
      System.IO.FileMode.Open, 
      System.IO.FileAccess.Read, 
      System.IO.FileShare.ReadWrite); 

     try 
     { 
      return CalcHashCode(stream); 
     } 
     finally 
     { 
      stream.Close(); 
     } 
    } 

    public static string CalcHashCode(FileStream file) 
    { 
     MD5CryptoServiceProvider md5Provider = new MD5CryptoServiceProvider(); 
     Byte[] hash = md5Provider.ComputeHash(file); 
     return Convert.ToBase64String(hash); 
    } 

MD5またはHashchecks

をチェックする必要があります。ストリームへのリンクを変換する方法を知らない人のために

通常のソリューションは、通常、ファイルのメタデータに、どこかのクラウドファイルのハッシュを保持し、ハッシュと比較することである

WebRequest req = HttpWebRequest.Create("url here"); 
using (Stream stream = req.GetResponse().GetResponseStream()) 
{ 

} 
+1

-1 **インターネット上のファイルへのリンク** –

+0

これはWindowsストアアプリです - FileStreamなし –

+0

@SriramSakthivelこれはちょうどHashCodeを計算するためのアイデアです。 OPは明らかに2つのリンクを持っている可能性があります、そうでなければ彼の最初の質問は、Windowsストアのアプリケーションのリンクの抽出に反対するでしょう –

0

今すぐあなたのアップデートで、それはあなたのコードが何をするかの種類のは明らかです:それは、与えられたもとで与えられたURLやアプリケーションデータフォルダに保存するから画像をダウンロードしますファイル名。任意のイメージを1回だけダウンロードしたいとします。

このコードをどのように呼び出すかはまだ分かりませんが、私の解決策は "URL to filename"の翻訳が必要なようです。だから、擬似で:

BitmapImage GetImage(string sourceURL) 
{ 
    string filename = GetFilenameForURL(sourceURL); 

    BitmapImage image; 

    if (!FileExists(filename)) 
    { 
     image = DownloadAndSaveImage(sourceURL, filename); 
    } 
    else   
    {  
     image = ReadImageFile(filename); 
    } 

    return image; 
} 

これは、サーバー上で更新されたイメージを考慮していません。これを行うには、DownloadAndSaveImage()コールにメタデータを保存する必要があります(たとえば、ETagまたはlast-modifiedの日付を参照)。

そして、帯域幅を節約するために、新しいバージョンが利用可能であるかどうかを確認するReadImageFile()の呼び出しの前if-none-matchif-modified-sinceヘッダーとHEADまたは条件GET要求を行うことができます。