8

我正在使用Zemanta API,它每次调用最多接受 8 KB 的文本。我正在使用 JavaScript 从网页中提取要发送到 Zemanta 的文本,因此我正在寻找一个能够将我的文本截断为 8 KB 的函数。

Zemanta 应该自己进行这种截断(即,如果您向其发送更大的字符串),但在进行 API 调用之前,我需要将这些文本来回移动一下,因此我希望将有效负载保持尽可能小。

假设 8 KB 的文本是 8,192 个字符并相应地截断是否安全?(每个字符 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 回答
2

你可以做这样的事情,因为 unescape 被部分弃用

function byteCount( string ) {
    // UTF8
    return encodeURI(string).split(/%..|./).length - 1;
}

function truncateByBytes(string, byteSize) {
    // UTF8
    if (byteCount(string) > byteSize) {
        const charsArray = string.split('');
        let truncatedStringArray = [];
        let bytesCounter = 0;
        for (let i = 0; i < charsArray.length; i++) {
            bytesCounter += byteCount(charsArray[i]);
            if (bytesCounter <= byteSize) {
                truncatedStringArray.push(charsArray[i]);
            } else {
                break;
            }
        }
        return truncatedStringArray.join('');
    }
    return string;
}
于 2018-08-24T01:11:42.033 回答
1

正如多米尼克所说,字符编码是问题所在 - 但是,如果您可以真正确保您只处理 8 位字符(不太可能但可能)或假设 16 位字符并将自己限制为可用空间的一半,即 4096 chars 那么你可以尝试这个。

不过,为此依赖 JS 是一个坏主意,因为它可以被简单地修改或忽略,并且您需要处理转义字符和编码的复杂性。最好使用 JS 作为首选过滤器并使用您可用的任何服务器端语言(这也将打开压缩)。

于 2009-10-04T08:23:52.757 回答