8

呼び出しごとに最大 8 KB のテキストを受け入れるZemanta APIを使用しています。JavaScript を使用して Web ページから Zemanta に送信するテキストを抽出しているので、テキストを正確に 8 KB に切り詰める関数を探しています。

Zemanta はこの切り捨てを独自に行う必要があります (つまり、より大きな文字列を送信する場合) が、API 呼び出しを行う前にこのテキストを少し移動する必要があるため、ペイロードをできるだけ小さく保ちたいと考えています。

8 KB のテキストが 8,192 文字であると仮定して、それに応じて切り捨てても安全ですか? (1 文字あたり 1 バイト、1 KB あたり 1,024 文字、8 KB = 8,192 バイト/文字) または、それは不正確ですか、それとも特定の状況でのみ当てはまるのでしょうか?

実際のファイル サイズに基づいて文字列を切り詰めるよりエレガントな方法はありますか?

4

4 に答える 4

13

シングルバイトエンコーディングを使用している場合、はい、8192 文字 = 8192 バイトです。UTF-16 を使用している場合、8192 文字 (*) = 4096 バイト。

(実際には 8192 のコードポイント。これはサロゲートの場合とは少し異なりますが、JavaScript はそうではないため、心配する必要はありません。)

UTF-8 を使用している場合、最小限のコードで JS に UTF-8 エンコーダー/デコーダーを実装するために使用できる簡単なトリックがあります。

function toBytesUTF8(chars) {
    return unescape(encodeURIComponent(chars));
}
function fromBytesUTF8(bytes) {
    return decodeURIComponent(escape(bytes));
}

これで、次のように切り捨てることができます:

function truncateByBytesUTF8(chars, n) {
    var bytes= toBytesUTF8(chars).substring(0, n);
    while (true) {
        try {
            return fromBytesUTF8(bytes);
        } catch(e) {};
        bytes= bytes.substring(0, bytes.length-1);
    }
}

(try-catch の理由は、マルチバイト文字シーケンスの途中でバイトを切り捨てると、無効な UTF-8 ストリームが取得され、decodeURIComponent が文句を言うからです。)

Shift-JIS や Big5 などの別のマルチバイト エンコーディングの場合は、自己責任です。

于 2009-10-04T13:36:30.350 に答える
2

一部の文字エンコーディングでは、各文字が複数のバイトを占めるため、8KB のテキストが 8192 文字であると想定するのは安全ではありません。

ファイルからデータを読み取っている場合、ファイルサイズを取得することはできませんか? それとも、8KB のチャンクで読み込みますか?

于 2009-10-04T08:11:01.253 に答える