しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure Blob Storage へのアップロード時にファイルの MD5 を同時に計算して保存する

Azure Blob へファイルなどをアップロードしたタイミングで、MD5 を計算してくれる便利な設定があるようです。アップロード前に自前でハッシュ値の計算をしなくても、この値を使って楽が出来そうです。

BlobRequestOptions.StoreBlobContentMD5 Property (Microsoft.WindowsAzure.Storage.Blob)

最初は出来ないと思ってましたが、この設定を Azure Storage の神ことおーみさんが教えてくれました。

アップロード時の処理と、保存された Blob から MD5 を取得する方法を試しました。

MD5 を保存する設定でアップロード

少し見た感じだと、コンテナ単位で設定出来そうな気がしないこともないですが、今回は BlobClient のデフォルト設定を書き換えてしまいます。

// ストレージアカウントを用意
var storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=**;AccountKey=**");

var blobClient = storageAccount.CreateCloudBlobClient();

// デフォルトの設定を書き換える
blobClient.DefaultRequestOptions = new BlobRequestOptions
{
    StoreBlobContentMD5 = true
};

// コンテナが無ければ作る
var container = blobClient.GetContainerReference("md5sample");
container.CreateIfNotExists();

// Blob へファイルをアップロード
var blob = container.GetBlockBlobReference("sample.txt");

blob.UploadFromFile(@"****.txt", FileMode.Open);

// ファイルの MD5 を表示
Console.WriteLine(blob.Properties.ContentMD5);

極めて普通の Blob へアップロードするコードですが、StoreBlobContentMD5 の設定だけ変えてます。

実際にアップロードして CloudBerry Explorer でメタデータを確認してみます。

f:id:shiba-yan:20150301183954p:plain

Content-MD5 にファイルの MD5 が Base64 で保存されています。これを使えばいいですね。

保存した MD5 を取得

アップロード直後には ContentMD5 プロパティで取れますが、後から取得したい場合には FetchAttributes メソッドを呼び出してから ContentMD5 プロパティを参照するようにします。

var container = blobClient.GetContainerReference("md5sample");
var blob = container.GetBlockBlobReference("sample.txt");

// メタデータだけを取得
blob.FetchAttributes();

// ファイルの MD5 を表示
Console.WriteLine(blob.Properties.ContentMD5);

これで ContentMD5 にちゃんとファイルのハッシュ値が入ってきます。

f:id:shiba-yan:20150301184208p:plain

おまけ

Azure Blob のメタデータは HTTP ヘッダーとして返されるので、ブラウザで直接アクセスして Content-MD5 を取得することも出来ます。実際に Chrome で確認してみました。

f:id:shiba-yan:20150301184309p:plain

全ての方法で同じ値が返ってきているので安心できます。

ちなみに Content-MD5 の値は Base64 されているので、よく見る MD5 のハッシュ値とは見た目が異なってます。なので、変換するコードを最後に載せておきます。

// Base64 からバイト配列に戻す
var buffer = Convert.FromBase64String(blob.Properties.ContentMD5);

// 16 進数の表記に変換
var hash = BitConverter.ToString(buffer).Replace("-", "").ToLower();

Console.WriteLine(hash);

これを実行すると、よく見る形式で表示されます。

f:id:shiba-yan:20150301185813p:plain

勝手に MD5 の計算をしてくれるのは、アップロード時にストリームを使う場合に便利だと思うので、これからは使っていきたいですね。MD5 で良いのかという気はしないこともないですが。