Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/415.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用JavaScript将文本截断为特定大小(8KB)_Javascript_Text_Byte_Truncate_Zemanta - Fatal编程技术网

使用JavaScript将文本截断为特定大小(8KB)

使用JavaScript将文本截断为特定大小(8KB),javascript,text,byte,truncate,zemanta,Javascript,Text,Byte,Truncate,Zemanta,我使用的是API,每次调用最多可接受8KB的文本。我正在使用JavaScript从网页中提取要发送给Zemanta的文本,因此我正在寻找一个函数,该函数将截短正好为8KB的文本 Zemanta应该自己做这个截断(即,如果您发送一个更大的字符串),但是在进行API调用之前,我需要将这个文本来回传递一点,所以我希望保持负载尽可能小 假设8KB的文本是8192个字符,并相应地截断是否安全?(每个字符1字节;每个KB 1024个字符;8 KB=8192个字节/字符)或者,这是不准确的还是仅在特定情况下才

我使用的是API,每次调用最多可接受8KB的文本。我正在使用JavaScript从网页中提取要发送给Zemanta的文本,因此我正在寻找一个函数,该函数将截短正好为8KB的文本

Zemanta应该自己做这个截断(即,如果您发送一个更大的字符串),但是在进行API调用之前,我需要将这个文本来回传递一点,所以我希望保持负载尽可能小

假设8KB的文本是8192个字符,并相应地截断是否安全?(每个字符1字节;每个KB 1024个字符;8 KB=8192个字节/字符)或者,这是不准确的还是仅在特定情况下才正确


有没有一种更优雅的方法可以根据字符串的实际文件大小来截断字符串?

没有,假设8KB的文本是8192个字符是不安全的,因为在某些字符编码中,每个字符都占满了


如果你正在从文件中读取数据,你就不能抓取文件大小吗?或者以8KB的数据块阅读它?

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


但是,依赖JS来实现这一点是个坏主意,因为它可以被简单地修改或忽略,并且您需要处理转义字符和编码等复杂问题。最好使用JS作为第一次机会过滤器,并使用任何可用的服务器端语言(这也将打开压缩)。

如果使用单字节编码,是的,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);
    }
}

(尝试捕获的原因是,如果截断多字节字符序列中间的字节,则会得到无效的UTF-8流,而译码器会抱怨)。


如果它是另一种多字节编码,如Shift JIS或Big5,则您可以自行处理。

由于部分不推荐使用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;
}
函数字节数(字符串){
//UTF8
返回encodeURI(字符串).split(/%.../).length-1;
}
函数截断字节(字符串,字节大小){
//UTF8
if(字节计数(字符串)>字节大小){
常量charsArray=string.split(“”);
设truncatedStringArray=[];
让bytesCounter=0;
for(设i=0;i如果(bytesCounter您可能想检查您正在处理的文本是否具有特定的编码,例如UTF-8、ASCII等?如果您确定文本只包含单字节字符,则截断将更简单。您将权衡一些灵活性。至于Zemanta将8KB视为8192字节还是8000字节,为什么不进行测试你自己解决吗?谢谢,好的。我认为Dominic是对的,这个文本(可能是UTF-8)可能会占用每个字符的多个字节,因此不可能基于字符数量进行测量。谢谢,Dominic-我使用JavaScript的.innerText()方法(而不是.txt文件或其他文件)从文档中收集这些文本,所以我不确定是否有办法指定“给我8 KB的数据”-这正是我理想中所寻找的。这正是我所寻找的-工作起来很有魅力!谢谢,bobince。这只是给后代一个很好的提示-我有点密集,所以我花了几分钟才意识到变量“unicodecharacters”和“utf8bytes”在您的函数中,这只是为了解释,实际上应该与参数匹配以起作用(即,在两个较短的函数中,两者都应替换为“s”)。再次感谢!哎呀!剪切和粘贴的危险就在这里。谢谢你,安纳卡塔-看起来bobince的函数在我的情况下会起作用。泽曼塔实际上应该删除超过8KB限制的任何文本,所以我不太关心他们的API最终会出现什么(当然,除了节省带宽之外),因为在这种情况下,客户端的最大性能增益将至少限制在8KB左右。