2012-04-02 10 views
2

私は文字列でビットを扱わなければならないerlangモジュールを書いていますが、あまり多くはありませんが、私はいくつかのtcp recvを行い、次にデータを解析します。デフォルトではErlangのバイナリ文字列

データを照合して文字列を操作している間、私はいつもbinary:split(Data,<<":">>)のようなバイナリモジュールを使用しており、基本的には<<"StringLiteral">>を使用しています。

これまでのところ、私は代替リスト(リストを使用しています)から方法が見つからず、<を追加する以外はすべて自然に出てきました。<を追加しましたが、このような文字列の処理方法私が気づいていない欠点があります。

ヒント?

答えて

4

文字列がバイナリでどのようにエンコードされているかを十分に認識する必要があります。あなたのコードで< < "StringLiteral" >>を実行する場合、これは単にコードポイントのリストのバイナリシリアル化であることに注意する必要があります。あなたのErlangコンパイラはあなたのコードをISO-8859-1文字として読んでいます。したがって、Latin-1文字のみを使用し、これを一貫して行う限り、うまくいくはずです。しかし、これは国際化にとってあまり親切ではありません。

今日のほとんどのアプリケーションソフトウェアでは、ユニコードエンコードが好まれるはずです。 UTF-8は最初の128コードポイントで< < "StringLiteral" >>と互換性がありますが、128コードポイントでは互換性がありませんので注意してください。あなたのコードに< < "StrïngLïteral" >>を使用すると、UTF-8でエンコードされたWebアプリケーションに表示される内容に驚くかもしれません。

< < "StrïngLterteral"/utf8 >>の形でバイナリサポートのEEP提案がありましたが、これは確定されていません。

分割しているIS0-8859-1バイトを含むマルチバイト文字がある場合は、バイナリ:split/2関数がUTF-8で予期しない結果になることがあることにも注意してください。

UTF-16は、より効率的に解析でき、32ビット文字が存在しないことを前提としている場合は、インデックスでより簡単に分割できるため、より優れたエンコーディングです。

unicode moduleは使用する必要がありますが、リテラルを使用する場合は注意深く実行してください。

3

注意しなければならないのは、バイナリはバイトスライスですが、リストはユニコードコードポイントのリストです。言い換えれば、前者は何らかのエンコーディング、通常はUTF-8を必要とするのに対し、後者は自然にUnicodeです。

私の知る限り、あなたの方法に欠点はありません。

5

あなたとあなたのチームがあなたの文字列がリストではなくバイナリであることを覚えている限り、このアプローチには固有の問題はありません。実際、Couch DBはこのアプローチを最適なものと見なし、明らかに素晴らしい配当を支払っていました。

2

バイナリは、文字列を格納するための非常に効率的な構造です。 64Bよりも長い場合は、プロセスヒープの外部にも格納されるため、GCの対象にはなりません(最後のrefが失われたときにはまだカウントされていません)。パフォーマンスが重要なときにコピーを避けるためにiolistsを連結に使用することを忘れないでください。

関連する問題