5

私の理解では、UTF8 または UTF16 でエンコードされたファイルへの読み取りは、時折のサロゲート バイト (東部言語などで使用される) のために必ずしもランダムであるとは限りません。

.NET を使用してファイル内のおおよその位置にスキップし、半ランダムな位置から Unicode テキストを読み取るにはどうすればよいですか?

サロゲート バイトを破棄し、ワード ブレークを待って読み取りを続行しますか? もしそうなら、デコードを開始するまで待つべき有効な単語区切りは何ですか?

4

3 に答える 3

8

簡単です。UTF-8 は自己同期です。
ファイル内のランダムなバイトにジャンプし、先頭のビット(継続バイト)を含むすべてのバイトをスキップして読み取るだけです。10先行していない最初のバイト10は、適切な UFT-8 文字の開始バイトであり、通常の UTF-8 エンコーディングを使用して後続のバイトを読み取ることができます。

于 2011-02-08T16:55:08.277 に答える
2

UTF-8ファイルから疑似ランダム文字を抽出しようとしていると仮定すると、私は個人的に、ランダムな場所にジャンプして、保証された「文字の開始」位置まで前方にスクロールする方法を考えようとするのをやめます(私の気持ちはトリッキーな提案になるでしょう)これを編集するの は間違っています。次のようなものはどうですか?

  1. ファイルの長さをバイト単位で設定します
  2. 文字数をヒューリスティックに推測します。たとえば、適切なコーパスから確立された定数でスケーリングします。またはn、このファイルをより代表する可能性のあるスケーリング定数を取得するために、最初のバイトを調べて、それらが何文字を記述しているかを確認します。
  3. で疑似乱数を選択します1..<guessed number of characters in file>
  4. ファイルが非常に大きい場合(私はそれがそうであるに違いないと思います、そうでなければあなたはこれを求めないでしょう)、バッファリングされた読み取りを使用して:
  5. 目的の文字に到達するまで、ファイルのバイトを読み取り、UTF-8にデコードします。ファイルの終わりから外れた場合は、最後のファイルを使用してください

ここでのバッファリングされた読み取りでは、文字のバイトが2つの読み取りに分割されたときにコンテキストが失われないように、交互に「最初」の2つのバッファを使用する必要があります。

読み取りバッファーA:バイト1000-1999読み取りバッファーB:バイト2000-2999

文字がバイトを占める場合1998-2001、単一のバッファーを使用するとコンテキストが失われます。

読み取りバッファA:バイト3000〜3999

バイトストリームを文字に変換すると、実際にはバッファAがバッファBの後に続きます。


以下の@jleedevで示されているように、また他の回答で見られるように、保証された文字の開始まで「スクロールフォワード」するの実際には簡単で安全です。しかし、上記の文字数の見積もりは、それでも役立つ可能性があります。

于 2011-02-08T16:34:13.287 に答える
1

UTF-16の場合、常に偶数バイトの位置にジャンプする必要があります。次に、後続のサロゲートが続くかどうかを確認できます。もしそうなら、それをスキップしてください、さもなければ、あなたは整形式のUTF-16コードユニットシーケンスの始めにいます(もちろん、ファイルが整形式であると常に仮定します)。

UnicodeエンコーディングUTF-8およびUTF-16は、自己同期するように特別に設計されており、多くても少数のコードユニットをスキップするだけでよいという強力な保証があります。

于 2011-02-09T14:32:03.997 に答える