我正在使用Zemanta API,每次调用最多可接受8 KB的文本。我正在使用JavaScript从网页中提取要发送给Zemanta的文本,所以我正在寻找一个能够以8 KB的速度截断我的文本的函数。
Zemanta应该自己进行截断(例如,如果你发送一个更大的字符串),但是我需要在进行API调用之前将这个文本稍微移动一下,所以我想保持有效负载尽可能小
假设8 KB的文本是8,192个字符并且相应地截断是否安全? (每个字符1个字节;每KB 1,024个字符; 8 KB = 8,192个字节/字符)或者,在某些情况下是不准确还是仅为真?
是否有更优雅的方法根据文件的实际文件大小截断字符串?
答案 0 :(得分:10)
如果您使用单字节编码,是,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,那么你就是自己的。
答案 1 :(得分:2)
不,假设8KB的文本是8192个字符是不安全的,因为在某些字符编码中,每个字符占用multiple bytes。
如果您正在从文件中读取数据,那么您是否只能抓取文件大小?或者以8KB的块读取它?
答案 2 :(得分:1)
正如多米尼克所说,字符编码是问题所在 - 但是如果你能真的确保你只处理8位字符(不太可能但可能)或假设16位字符和将自己限制在可用空间的一半,即4096个字符,然后你可以尝试这个。
依靠JS来做这个是一个坏主意,因为它可以被简单地修改或忽略,并且你有例如转义字符和编码的复杂性。最好使用JS作为第一次机会过滤器并使用您可用的任何服务器端语言(这也将打开压缩)。
答案 3 :(得分:1)
由于不建议使用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;
}