Azure Storage の BLOBオブジェクトの MetaData に日本語を格納

| コメント(0) | トラックバック(0) このエントリーを含むはてなブックマーク

前回の Windows Azure 体験3 でMetaDataの保存方法について記載した。今回は、ここの記載方法について検討してみた。

Windows Azure StorageのMetaData

BLOB等のMetaDataは、HTTPヘッダに記録されるらしく、日本語が通らないそうである。 したがって、string 文字列を直接格納すると、USC-2なために問題が発生する。

なので、7bitオンリーな文字にすれば良いという事で変換作業をすることにする。

MetaDataへのアクセスコード

前回の Windows Azure 体験3 のコードを再掲載しておく。 ただ、今回テストしやすいように以下のように記述した。

  • MetaDataに保存
var block = container.GetBlockBlobReference(uniqBlobName);
block.Metadata["title"] = ConvertToAsciiOnlyString(TitleTextBox.Text);
block.UploadFromStream(FileUpload1.FileContent);
 
 

ここでは、ConvertToAsciiOnlyStringを用意して、StringからASCIIオンリーな文字列に変換した。

  • MetaDataから取得
repeater.DataSource = from o in blobs
    select new
    {
        Url = o.Uri,
        Title =ConvertFromoAsciiOnlyString(o.Metadata["title"])
    };
 
 

UTF-7案

前回の案はUTF-7に変換する案である。 UTF-7は以下のような形式である。

UTF-16 (後述)で表したUnicodeをBase64で変換して表す符号化方式。 ただし、ASCIIのアルファベット範囲等についてはBase64に変換しない等、 特殊な符号化スキームを行う。RFC-2152で定められており、 Unicode標準及びUnicodeの関連仕様には含まれない。 かつてのSMTP等のように、7ビット単位でしかデータを扱えない通信方式を 利用する場合を想定して作られている。ステートフルエンコーディングであり、 運用上問題が多いため、現在ではこの方式は推奨されていない。 Unicode文字を7ビット単位伝送通信にどうしても通さなければならない場合は、 替わりにUTF-8をQuoted-printableあるいはBase64で変換するなどの方式が好ましいとされる。

Unicodeエンコーディング(符号化方式) より

ということで、以下のコードを利用していた。

コード

string ConvertToAsciiOnlyString(string src)
{
    var bytes = System.Text.Encoding.UTF7.GetBytes(src);
    return System.Text.Encoding.ASCII.GetString(bytes);
}

string ConvertFromoAsciiOnlyString(string asciiOnlyString)
{
    var bytes = System.Text.Encoding.ASCII.GetBytes(asciiOnlyString);
    return System.Text.Encoding.UTF7.GetString(bytes);
}
 
 

この方式について

Wikipediaの記載にもあるように、事実上使用しない方がよいだろうという事で、 廃案とする。

UTF-8 + Base64案

Wikipediaの案

Unicode文字を7ビット単位伝送通信にどうしても通さなければならない場合は、 替わりにUTF-8をQuoted-printableあるいはBase64で変換するなどの方式が好ましいとされる。

Unicodeエンコーディング(符号化方式) より

を採用すると以下のようになった

コード

string ConvertToAsciiOnlyString(string src)
{
    var bytes = System.Text.Encoding.UTF8.GetBytes(src);
    return System.Convert.ToBase64String(bytes);
}

string ConvertFromoAsciiOnlyString(string asciiOnlyString)
{
    var bytes = System.Convert.FromBase64String(asciiOnlyString);
    return System.Text.Encoding.UTF8.GetString(bytes);
}
 
 

サイズ計算

よくよく計算すると以下のようになった。

Base64変換の手順を以下に挙げる。

1.元データを6bitずつに分割。(6bitに満たない分は0を追加して6bitにする)

2.各6bitの値を変換表を使って4文字ずつ変換。(4文字に満たない分は = 記号を追加して4文字にする)

Base64変換形式 より

上記の事を考慮すると、日本語文字列は UTF-8 では 3byte。つまり3x8bitとなり24bit必要となる。 この24bitを6bit4つに分解し、それぞれに1文字を割当てると4byte必要となる。

URLエンコード案

URLエンコードを使う案を検討する。 HttpUtility.UrlEncodeは、渡された文字列をURLエンコードしてくれる。 この時日本語などの文字列はUTF-8に変換され、そのあと変換される。

コード

string ConvertToAsciiOnlyString(string src)
{
    return HttpUtility.UrlEncode(src);
}

string ConvertFromoAsciiOnlyString(string asciiOnlyString)
{
    return HttpUtility.UrlDecode(asciiOnlyString);
}
 
 

サイズ計算

日本語文字列は UTF-8 では 3byte。1byteあたり'%'と16進数2文字つまり3byteにエンコードされる。 これを踏まえると、日本語1文字をURLエンコードすると9byte必要となる。 ただ、日本語ではバイト数が増えるが、アスキー単体ではそのまま表記が可能であるため、悩ましい。

まとめ

以上の事を考えると

  • UTF-8 + Base64案
  • URLエンコード案

以上の2つが有効と考えられる。

もに日本語文字列が多い場合には、UTF-8 + Base64案を採用すればよいかと考える。 ただ、アルファベットのみの可能性も多い場合、URLエンコード案も捨てがたいと思う。

トラックバック(0)

トラックバックURL: http://www.m-tea.info/mt-tb.cgi/44

コメントする

あわせて読みたいブログパーツ

このブログ記事について

このページは、k1ha410が2009年12月17日 22:54に書いたブログ記事です。

ひとつ前のブログ記事は「Windows Azure 体験3」です。

次のブログ記事は「IronRuby 1.0 RC1のリリース」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。