私の理解では、UTF8 または UTF16 でエンコードされたファイルへの読み取りは、時折のサロゲート バイト (東部言語などで使用される) のために必ずしもランダムであるとは限りません。
.NET を使用してファイル内のおおよその位置にスキップし、半ランダムな位置から Unicode テキストを読み取るにはどうすればよいですか?
サロゲート バイトを破棄し、ワード ブレークを待って読み取りを続行しますか? もしそうなら、デコードを開始するまで待つべき有効な単語区切りは何ですか?
私の理解では、UTF8 または UTF16 でエンコードされたファイルへの読み取りは、時折のサロゲート バイト (東部言語などで使用される) のために必ずしもランダムであるとは限りません。
.NET を使用してファイル内のおおよその位置にスキップし、半ランダムな位置から Unicode テキストを読み取るにはどうすればよいですか?
サロゲート バイトを破棄し、ワード ブレークを待って読み取りを続行しますか? もしそうなら、デコードを開始するまで待つべき有効な単語区切りは何ですか?
簡単です。UTF-8 は自己同期です。
ファイル内のランダムなバイトにジャンプし、先頭のビット(継続バイト)を含むすべてのバイトをスキップして読み取るだけです。10
先行していない最初のバイト10
は、適切な UFT-8 文字の開始バイトであり、通常の UTF-8 エンコーディングを使用して後続のバイトを読み取ることができます。
UTF-8ファイルから疑似ランダム文字を抽出しようとしていると仮定すると、私は個人的に、ランダムな場所にジャンプして、保証された「文字の開始」位置まで前方にスクロールする方法を考えようとするのをやめます(私の気持ちはトリッキーな提案になるでしょう)これを編集するの は間違っています。次のようなものはどうですか?
n
、このファイルをより代表する可能性のあるスケーリング定数を取得するために、最初のバイトを調べて、それらが何文字を記述しているかを確認します。1..<guessed number of characters in file>
ここでのバッファリングされた読み取りでは、文字のバイトが2つの読み取りに分割されたときにコンテキストが失われないように、交互に「最初」の2つのバッファを使用する必要があります。
読み取りバッファーA:バイト1000-1999読み取りバッファーB:バイト2000-2999
文字がバイトを占める場合1998-2001
、単一のバッファーを使用するとコンテキストが失われます。
読み取りバッファA:バイト3000〜3999
バイトストリームを文字に変換すると、実際にはバッファAがバッファBの後に続きます。
以下の@jleedevで示されているように、また他の回答で見られるように、保証された文字の開始まで「スクロールフォワード」するのは実際には簡単で安全です。しかし、上記の文字数の見積もりは、それでも役立つ可能性があります。
UTF-16の場合、常に偶数バイトの位置にジャンプする必要があります。次に、後続のサロゲートが続くかどうかを確認できます。もしそうなら、それをスキップしてください、さもなければ、あなたは整形式のUTF-16コードユニットシーケンスの始めにいます(もちろん、ファイルが整形式であると常に仮定します)。
UnicodeエンコーディングUTF-8およびUTF-16は、自己同期するように特別に設計されており、多くても少数のコードユニットをスキップするだけでよいという強力な保証があります。