前回の 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で変換するなどの方式が好ましいとされる。
ということで、以下のコードを利用していた。
コード
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で変換するなどの方式が好ましいとされる。
を採用すると以下のようになった
コード
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エンコード案も捨てがたいと思う。


コメントする