如何将数组缓冲区转换为字符串
how to convert arraybuffer to string
我在node.js上编写了一个简单的TCP服务器,用于向Chrome应用程序发送一些数据。在chrome应用程序中,当我获得数据时,我使用下面的函数将其转换为字符串,我得到一个异常"Uint16Array的字节长度应该是2的倍数"
String.fromCharCode.apply(null, new Uint16Array(buffer))
我找不到任何关于是什么原因导致的以及如何解决的信息。如有任何意见,我们将不胜感激。
以下是node.js服务器中用于向客户端发送数据的代码:
socket.on('data', function(data) {
console.log('DATA ' + socket.remoteAddress + ': ' + data);
// Write the data back to the socket,
// the client will receive it as data from the server
var r= socket.write('from server'r'n');
});
以下是chrome应用程序的代码:
chrome.sockets.tcp.onReceive.addListener(function (info) {
console.log('onListener registered');
if (info.socketId != socketid)
return;
else {
try {
data = ab2str(info.data);
console.log(data);
}
catch (e) {
console.log(e);
}
}
// info.data is an arrayBuffer.
});
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
实现这一点的现代(Chrome 38+)方法是,假设编码为UTF-8:
var decoder = new TextDecoder("utf-8");
function arrayBufferToString(buffer) {
return decoder.decode(new Uint8Array(buffer));
}
这使用TextDecoder
API;有关更多选项,例如不同的编码,请参阅文档。
另请参阅:Easier ArrayBuffer<->;使用编码API进行字符串转换@谷歌开发者
您可能会看到这个问题,因为您的应用程序在套接字上接收到奇数个字节,但您正试图从中创建一个2字节宽的项目数组(因为这适合Uint16Array
)
如果你的应用程序通过网络接收到字符串"Hello"
(5字节),那么你可以将其转换为Uint8Array
,它看起来像这样:
Item: 0 1 2 3 4
Char: H e l l o
Uint8 Value: 72 101 108 108 111
将其投射到Uint16Array
,不过会尝试这样做:
Item 0 1 2
Chars He ll o?
IntVal 25928 27756 ?????
如果没有第6个字节,它就无法构造数组,因此会出现异常。
只有当您期望套接字上有UCS-2字符串数据时,对数据使用Uint16Array
才有意义。如果您接收的是纯ASCII数据,那么您希望将其转换为Uint8Array
,并在其上映射String.fromCharCode
。如果是其他内容,比如UTF-8,那么您将不得不进行其他转换。
不管怎样,套接字层总是可以自由地向您发送任何长度的数据块。你的应用程序必须处理奇数大小的数据,并保存你无法立即处理的剩余数据,这样你就可以在收到下一块数据时使用它。
有点过时了,但使用这个函数(原始源)可能效果更好(它对我来说可以将arraybuffer解码为字符串,而不会留下一些特殊字符作为总垃圾):
function decodeUtf8(arrayBuffer) {
var result = "";
var i = 0;
var c = 0;
var c1 = 0;
var c2 = 0;
var data = new Uint8Array(arrayBuffer);
// If we have a BOM skip it
if (data.length >= 3 && data[0] === 0xef && data[1] === 0xbb && data[2] === 0xbf) {
i = 3;
}
while (i < data.length) {
c = data[i];
if (c < 128) {
result += String.fromCharCode(c);
i++;
} else if (c > 191 && c < 224) {
if( i+1 >= data.length ) {
throw "UTF-8 Decode failed. Two byte character was truncated.";
}
c2 = data[i+1];
result += String.fromCharCode( ((c&31)<<6) | (c2&63) );
i += 2;
} else {
if (i+2 >= data.length) {
throw "UTF-8 Decode failed. Multi byte character was truncated.";
}
c2 = data[i+1];
c3 = data[i+2];
result += String.fromCharCode( ((c&15)<<12) | ((c2&63)<<6) | (c3&63) );
i += 3;
}
}
return result;
}
使用Blob
和FileReader
有一种异步方式。
您可以指定任何有效的编码。
function arrayBufferToString( buffer, encoding, callback ) {
var blob = new Blob([buffer],{type:'text/plain'});
var reader = new FileReader();
reader.onload = function(evt){callback(evt.target.result);};
reader.readAsText(blob, encoding);
}
//example:
var buf = new Uint8Array([65,66,67]);
arrayBufferToString(buf, 'UTF-8', console.log.bind(console)); //"ABC"
- 如何使用JQuery在Javascript中转换字符串中的HTML元素
- 将JSON插入MongoDB中,自动转换字符串中的日期
- 以点表示法转换字符串以获取对象引用
- 在 JavaScript 中转换字符串 11/28/2014 11:00 AM 到现在
- 为什么在主干的字符串数组中转换字符串数组
- 如何简单地转换字符串
- AngularJS如何转换字符串“;yyyyMMdd”;迄今为止
- 如何防止htmlspecialchar(PHP)转换字符串中的整数
- 刷新Aurelia中的i18n转换字符串插值
- 发布时禁用转换字符串
- 转换字符串货币
- 在javascript ajax调用中转换字符串到数组
- 转换字符串包含时间到24小时的时间,我可以做数学与- jQuery
- IE javascript引擎在转换字符串到日期时呈现NaN
- 如何转换字符串“a,b,c,d……”成a.b (c, d . .);来执行
- 如何在javascript中转换字符串到日期格式
- 如何在嵌套数组中转换字符串数组
- 在javascript中转换字符串日期
- 转换字符串在印度格式的javascript
- Javascript转换字符串到数组的对象