2

バイナリ データと UTF-8 エンコード データが混在するファイルがあります。

それは何かのように見えます

-----------------
|  Binary data  |
| (unknown len) |
+---------------+
|   Delimiter   |
+---------------+
|  UTF-8 string |   <--- only relevant part of file
+---------------+
|   Delimiter   |
+---------------+
|  Binary data  |
-----------------

テキストを抽出しようとしていますが、バイナリ コンテンツは気にしません。ファイルをすべてを UTF-8 としてデコードする文字列に読み込んでから、 を使用しNSScannerて区切り記号を見つけます。

私の懸念は、バイナリ データの内容によっては、UTF-8 としてデコードすると、デリミタを見つけることができなくなるオフセットの問題が発生する可能性があることです。(デリミタの直前のデータが次のシーケンスを複数のバイトとして解析し、失われるとします。)

このコードは特定のコンテンツで問題が発生しますか?

NSString *fileContents = [NSString stringWithContentsOfFile:path
                                                   encoding:NSUTF8StringEncoding
                                                      error:NULL];
NSScanner *scanner = [NSScanner scannerWithString:fileContents]
[scanner scanUpToString@"<DELIMITER>" intoString:nil];
// TODO: remove delimiter
NSString *desiredString;
[scanner scanUpToString:@"<DELIMITER2>" intoString:&desiredString];
4

2 に答える 2

3

<DELIMITER>UTF-8 マルチバイト シーケンスは、0x80 ~ 0xFF の範囲のバイトのみで構成されるため、区切り文字が文字どおり (および)のとおりであると仮定すると<DELIMITER2>、それらはマルチバイト シーケンスの一部にならない文字のみで構成されます。(すべての純粋な ASCII 文字列には、このプロパティがあります。)

ただし、UTF-8 シーケンスにも長さのラベルが付いています。たとえば、3 バイトのシーケンスがある場合

E2 80 3C

E2 は、それが 3 バイト シーケンスの最初のバイトであることを示しますが、3C をそのシーケンスの一部にすることはできません。UTF-8 デコーダーエラーをスローするか、2 つのコードポイント シーケンス U+FFFD U+003C を生成する必要がありますが、代わりに 3C を食べて 1 つの置換文字のみを生成するデコーダーに驚かないでしょう。

したがって、あなたが提案するものは安全ではなく、代わりに (oh71zb が示唆するように) ファイルをバイナリとして読み取り、区切り文字をスキャンし、その間にあるものを抽出してから、それらのバイトを UTF-8 として解釈する必要があります。

于 2013-06-24T21:20:28.543 に答える
2

そうです、心配する必要があります。原則として、デリミタの選択と UTF-8 デコーダの実装に応じて、デリミタの先頭からのいくつかのバイトが、先頭のバイナリ データによって形成されている一部の Unicode 文字の最後のバイトとしてデコードされる場合があります。

この場合、すべての文字が<DELIMITER>7 ビット ascii セット内に収まるのに対し、マルチバイト UTF-8 文字のすべてのバイトは、すべてのバイトに 8 番目 (高位) のビットが設定されるため、幸運になる可能性があります ( http ://en.wikipedia.org/wiki/UTF-8#説明)。UTF-8 デコーダーは、'<' を '<' 以外のものとして取得するべきではありませんが、私はそれを期待しません。

ファイルの内容をバイナリバイト配列/バッファとして読み込み、区切り記号を付けることは確かに良い考えです(そして、何らかの理由でバイナリデータの途中に突然ランダムに表示されないようにしてください...そのような発生区切り文字を含めることができないようにエスケープするか、バイナリ データを何らかの方法でエンコードする必要があります)、区切り文字の間の utf-8 エンコード文字列を抽出してから、utf-8 デコードを行います。

于 2013-06-24T21:07:30.207 に答える