ファイルでもメモリバッファでもネットワークストリームでもいいけど、なにかデジタルデータを与えられて、「これはテキストですか、バイナリーですか?」と聞かれたとしましょう。この質問に答えるのは難しい、とても難しいですね。
バイト列をじっと見つめる
目の前にあるのは何はともあれバイト列です。その意味では、すべてのデジタルデータはバイナリーだと言えます。これは否定しがたい事実ですが、だからといってテキストって概念が無意味ってわけじゃありません。テキストデータなしで我々は何もできませんもの。
バイト列をじっと見ていると、それがテキストか否か分かるのでしょうか? バイトパターンから推測できると言う人もいるでしょう(そしてある程度は正しいのです)が、推測なんてロクなもんじゃありません。バイト列自身には、テキストかバイナリーかを区別する印はないのです。
バイト列以外にメタデータが必要です。いま、バイト列に添えてisTextというブーリアンのフラグがあったとしましょう。フラグですから1ビットでも足ります(そうケチケチするこたーないけど)。これで解決ですよ。
- isTextの値がturなら、そのバイト列はテキストである。
- isTextの値がfalseなら、そのバイト列はバイナリーである。
あ、いや、ちょっと待った。バイト列をテキスト(文字の並び)と解釈するには文字符号化方式が必要ですね。encodignというメタデータも付けましょう。encodingの値は文字符号化方式の名前です。その名前文字列の文字符号化方式は? ってキリがないのでus-asciiに固定しておきます。
結局、バイト列以外に次のメタデータがあればいいことになります。
isText | encoding | 説明 |
---|---|---|
true | 文字符号化方式の名前 | バイト列を文字の並びと解釈できる |
false | (不要、無意味) | バイト列をそのまま扱う |
encodingだけでisTextフラグを代用もできますが、意味が違うので2つのメタデータに分離しておいたほうが分かりやすいでしょう。
型システムがあるとき
単に「テキストかバイナリーか」より詳しいデータの分類には、MIMEメディアタイプなどがあります。プログラミング言語の型システム*1もまたデータの分類体系を提供します。
型システムに、stringとbinaryというデータ型があったとします。あるデータがstring型だとは、前節で述べたバイト列とメタデータが次のようにセットにされていることです。
- バイト列
- isText = true
- 適切なencodingの値(例えば"utf-8")
binary型ならば、次のセットです。
- バイト列
- isText = false
特に問題はありませんね。では、stringまたはbinaryと型が付いているデータ(typed data)にisTextフラグを組み合わせたものを考えてみましょう。
番号 | isText | データ型 |
---|---|---|
1 | true | string |
2 | true | binary |
3 | false | string |
4 | false | binary |
1番と4番は、メタデータ情報が冗長なだけで矛盾はしていません。2番と3番は、isTextフラグと型が矛盾しています。矛盾しているからエラーという判断もアリなんですが、次のような解釈も可能です。
- 2番: バイナリーデータを、適当な文字符号化方式でデコードしてテキストと解釈する。もちろん、文字符号化方式の指定が必要。
- 3番: テキストーデータの文字符号化方式の情報を捨て去り、バイト列部分だけを残して、単なるバイナリーとみなす。
いつでもこんな解釈が意味を持つわけじゃないですが、ときに有効なこともります。まとめておくと:
番号 | isText | データ型 | 文字符号化方式 | 処理 |
---|---|---|---|---|
1 | true | string | 既に決まっている | 特になし |
2 | true | binary | 別途与える | デコード |
3 | false | string | 不要 | バイト列だけにする |
4 | false | binary | 不要 | 特になし |