- 概述
- 创建 StringIO 对象
- 方法
- utf8Encode 方法
- utf8Decode 方法
- utf8Length 方法
- utf16Length 方法
- isUTF8 方法
- StringIO.prototype 上的方法
- length 方法
- position 方法
- mark 方法
- reset 方法
- clear 方法
- writeByte 方法
- writeInt32BE 方法
- writeUInt32BE 方法
- writeInt32LE 方法
- writeUInt32LE 方法
- writeUTF16AsUTF8 方法
- writeUTF8AsUTF16 方法
- write 方法
- readByte 方法
- readChar 方法
- readInt32BE 方法
- readUInt32BE 方法
- readInt32LE 方法
- readUInt32LE 方法
- read 方法
- skip 方法
- readString 方法
- readUntil 方法
- readUTF8 方法
- readUTF8AsUTF16 方法
- readUTF16AsUTF8 方法
- take 方法
- toString 方法
- clone 方法
- trunc 方法
概述
在高版本浏览器和 node.js 中,JavaScript 提供了 ArrayBuffer
和 Uint8Array
等 TypedArray
可以对二进制数据进行操作。但在低版本浏览器中并没有这些对象,而且这些对象没有自动伸缩性,不方便流式操作,相互转换也比较麻烦。
为兼容低版本浏览器,并且可以方便操作字符串和二进制数据,hprose for JavaScript 提供了一个 StringIO
对象。StringIO
是一个可自动伸缩的,可流式读写数据的工具类。
创建 StringIO 对象
- new StringIO();
- new StringIO(data);
- new StringIO(data[, strOffset[, length]]);
不带参数的构造器创建一个空的 StringIO
对象。空的 StringIO
对象可以进行写操作。
带 1 个参数的构造器,其中 data
参数是 String
类型的对象,如果是其它类型的对象,将会自动调用其上的 toString()
方法转换为 String
类型的对象。
带 2-3 个参数的构造器,其中 data
参数为 String
类型的对象,strOffset
为起始偏移量,length
为数据长度。
方法
utf8Encode 方法
- StringIO.utf8Encode(str);
该方法的功能是将 UTF-16
编码的字符串 str
转换为 UTF-8
编码的二进制字符串作为结果返回,str
本身不会被修改。
其中,str
参数为 String
类型的对象。
如果 str
不是正确的 UTF-16
编码的字符串,会抛出信息为 Malformed string
的异常。
例如:
- var StringIO = hprose.StringIO;
- console.log(StringIO.utf8Encode('你好'));
- console.log(StringIO.utf8Encode('????'));
执行结果为:
ä½ å¥½
ð¨ð³ðºð¸
utf8Decode 方法
- StringIO.utf8Decode(binstr);
该方法的功能是将 UTF-8
编码的二进制字符串 binstr
解码成普通的 UTF-16
编码的 JavaScript 字符串作为结果返回,binstr
本身不会被修改。
其中,binstr
参数为 String
类型的对象。
如果 binstr
不是正确的 UTF-8
编码的二进制字符串,会抛出异常。
例如:
- var StringIO = hprose.StringIO;
- console.log(StringIO.utf8Decode('ä½ å¥½'));
- console.log(StringIO.utf8Decode('ð¨ð³ðºð¸'));
执行结果为:
你好
????
utf8Length 方法
- StringIO.utf8Length(str);
该方法的参数 str
为 UTF-16
编码的字符串,该方法的返回值为将 str
转换为 UTF-8
编码的二进制字符串的长度,str
本身不会被修改。
其结果与:
- StringIO.utf8Encode(str).length
相同,但是 utf8Length
速度更快。
例如:
- var StringIO = hprose.StringIO;
- console.log(StringIO.utf8Length('你好'));
- console.log(StringIO.utf8Length('????'));
- console.log(StringIO.utf8Encode('????').length);
执行结果为:
6
16
16
utf16Length 方法
- StringIO.utf16Length(binstr);
该方法的参数 binstr
为 UTF-8
编码的字符串,该方法的返回值为将 binstr
转换为 UTF-16
编码的字符串的长度,binstr
本身不会被修改。
其结果与:
- StringIO.utf8Decode(binstr).length
相同,但是 utf16Length
速度更快。例如:
- var StringIO = hprose.StringIO;
- console.log(StringIO.utf16Length('ä½ å¥½'));
- console.log(StringIO.utf16Length('ð¨ð³ðºð¸'));
- console.log(StringIO.utf8Decode('ð¨ð³ðºð¸').length);
执行结果为:
2
8
8
isUTF8 方法
- StringIO.isUTF8(str);
该方法的判断参数 str
是否为 UTF-8
编码的二进制字符串,是返回 true,否则返回 false。
例如:
- var StringIO = hprose.StringIO;
- console.log(StringIO.isUTF8('hello'));
- console.log(StringIO.isUTF8('你好'));
- console.log(StringIO.isUTF8('ð¨ð³ðºð¸'));
true
false
true
StringIO.prototype 上的方法
下面我们用 stringIO
这个变量名来指代 StringIO
的实例对象。
length 方法
- stringIO.length();
该方法返回当前 stringIO
对象的长度。
position 方法
- stringIO.position();
该方法返回在对 stringIO
对象进行读取操作时的当前位置。当 position
返回值为 0 时,表示位于数据的开头,当 position
返回值与 length
返回值相同时,表示已没有可读取的数据。
mark 方法
- stringIO.mark();
保存当前的读写位置。如果对该方法进行多次调用,则只有最后一次保存的读写位置可以被恢复。
无返回值。
reset 方法
- stringIO.reset();
恢复由 mark
方法保存的读写位置。
无返回值。
clear 方法
- stringIO.reset();
清空 stringIO
对象,并将读写位置归零。
无返回值。
writeByte 方法
- stringIO.writeByte(byte);
往 stringIO
对象的末尾写入一个字节。
byte 的范围是 0-255 的整数。
执行成功后,stringIO
对象的 length
属性将会相应加 1。
无返回值。
writeInt32BE 方法
- stringIO.writeInt32BE(int32);
往 stringIO
对象的末尾按照 BigEndian 方式写入一个32位有符号整数(4个字节)。
int32
的范围是从 -2147483648 到 2147483647,超出范围会抛出 TypeError('value is out of bounds')
的异常。
执行成功后,stringIO
对象的 length
属性将会相应加 4。如果容量不足,将会自动扩容。
无返回值。
writeUInt32BE 方法
- stringIO.writeUInt32BE(uint32);
往 stringIO
对象的末尾按照 BigEndian 方式写入一个32位无符号整数(4个字节)。
uint32
的范围是从 0 到 4294967295,超出范围会抛出 TypeError('value is out of bounds')
的异常。
执行成功后,stringIO
对象的 length
属性将会相应加 4。如果容量不足,将会自动扩容。
无返回值。
writeInt32LE 方法
- stringIO.writeInt32LE(int32);
往 stringIO
对象的末尾按照 LittleEndian 方式写入一个32位有符号整数(4个字节)。
int32
的范围是从 -2147483648 到 2147483647,超出范围会抛出 TypeError('value is out of bounds')
的异常。
执行成功后,stringIO
对象的 length
属性将会相应加 4。如果容量不足,将会自动扩容。
无返回值。
writeUInt32LE 方法
- stringIO.writeUInt32LE(uint32);
往 stringIO
对象的末尾按照 LittleEndian 方式写入一个32位无符号整数(4个字节)。
uint32
的范围是从 0 到 4294967295,超出范围会抛出 TypeError('value is out of bounds')
的异常。
执行成功后,stringIO
对象的 length
属性将会相应加 4。如果容量不足,将会自动扩容。
无返回值。
writeUTF16AsUTF8 方法
- stringIO.writeUTF16AsUTF8(str);
往 stringIO
对象的末尾以 UTF-8
编码方式写入 UTF-16
编码的字符串 str
。
执行成功后,stringIO
对象的 length
属性将会增加相应的长度。
无返回值。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- stringIO.writeUTF16AsUTF8('你好');
- console.log(stringIO.length());
- stringIO.writeUTF16AsUTF8('????');
- console.log(stringIO.length());
6
22
writeUTF8AsUTF16 方法
- stringIO.writeUTF8AsUTF16(binstr);
往 stringIO
对象的末尾以 UTF-16
编码方式写入 UTF-8
编码的二进制字符串 binstr
。
执行成功后,stringIO
对象的 length
属性将会增加相应的长度。
无返回值。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- stringIO.writeUTF8AsUTF16('ä½ å¥½');
- console.log(stringIO.length());
- stringIO.writeUTF8AsUTF16('ð¨ð³ðºð¸');
- console.log(stringIO.length());
- console.log(stringIO.toString());
2
10
你好????
write 方法
- stringIO.write(data);
往 stringIO
对象的末尾写入数据 data
,对数据 data
不做编解码处理。
执行成功后,stringIO
对象的 length
属性将会增加相应的长度。
无返回值。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- stringIO.write('你好');
- console.log(stringIO.length());
- stringIO.write('????');
- console.log(stringIO.length());
- stringIO.write(3.14);
- console.log(stringIO.length());
- console.log(stringIO.toString());
2
10
14
你好????3.14
readByte 方法
- stringIO.readByte();
从 stringIO
对象的当前位置读取一个字节,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 1。
如果当前位置已在结尾,则返回 -1。
注意:该方法仅对二进制编码的数据有效。如果内容中包含有 UTF-16
编码的字符串,返回的将是 UTF-16
的字符的数字编码,该编码可能会大于 255。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- var i, n;
- stringIO.writeUTF16AsUTF8('你好');
- for (i = 0, n = stringIO.length(); i < n; i++) {
- console.log(stringIO.readByte());
- }
- console.log('----');
- stringIO.write('你好');
- for (i = n, n = stringIO.length(); i < n; i++) {
- console.log(stringIO.readByte());
- }
- console.log('----');
- console.log(stringIO.readByte());
228
189
160
229
165
189
----
20320
22909
----
-1
readChar 方法
- stringIO.readChar();
从 stringIO
对象的当前位置读取一个字符,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 1。
如果当前位置已在结尾,则返回 ''。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- var i, n;
- stringIO.writeUTF16AsUTF8('你好');
- for (i = 0, n = stringIO.length(); i < n; i++) {
- console.log(stringIO.readChar());
- }
- console.log('----');
- stringIO.write('你好');
- for (i = n, n = stringIO.length(); i < n; i++) {
- console.log(stringIO.readChar());
- }
ä
½
å
¥
½
----
你
好
readInt32BE 方法
- stringIO.readInt32BE();
从 stringIO
对象的当前位置读取 4 个字节,按照 BigEndian 编码方式转换为一个 32 位有符号整型数,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 4。
如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF')
异常。
readUInt32BE 方法
- stringIO.readUInt32BE();
从 stringIO
对象的当前位置读取 4 个字节,按照 BigEndian 编码方式转换为一个 32 位无符号整型数,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 4。
如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF')
异常。
readInt32LE 方法
- stringIO.readInt32LE();
从 stringIO
对象的当前位置读取 4 个字节,按照 LittleEndian 编码方式转换为一个 32 位有符号整型数,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 4。
如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF')
异常。
readUInt32LE 方法
- stringIO.readUInt32LE();
从 stringIO
对象的当前位置读取 4 个字节,按照 LittleEndian 编码方式转换为一个 32 位无符号整型数,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 4。
如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF')
异常。
read 方法
- stringIO.read(n);
从 stringIO
对象的当前位置读取长度为 n
的字符串,并返回。
执行成功后,stringIO
对象的 position
属性将会相应加 n
。
如果当前位置到结尾不足 n
个字符,则读取全部剩余字符并返回,stringIO
对象的 position
属性将被设置为与 length
相同。
skip 方法
- stringIO.skip(n);
从 stringIO
对象的当前位置略过 n
个字符,并返回实际略过的字符数。
执行成功后,stringIO
对象的 position
属性将会相应加 n。
如果当前位置到结尾不足 n
个字符,则略过全部剩余字符并返回略过的剩余字符数,stringIO
对象的 position
属性将被设置为与 length
相同。
readString 方法
- stringIO.readString(tag);
从 stringIO
对象的当前位置开始读取,直到遇到与 tag
相同的字符为止,并以字符串返回。
执行成功后,stringIO
对象的 position
属性将会相应增加读取到的字符数。
读取到的字符串中包含有最后的 tag
字符。
如果读取到结尾仍然没有遇到与 tag
相同的字符,则返回所有剩余的字符,stringIO
对象的 position
属性将被设置为与 length
相同。
readUntil 方法
- stringIO.readUntil(tag);
从 stringIO
对象的当前位置开始读取,直到遇到与 tag
相同的字节为止,并以字符串返回。
执行成功后,stringIO
对象的 position
属性将会相应增加读取到的字符数。
读取到的数据中不包含有最后的 tag
字符。但在位置计算上会算上 tag
字符。这是它与 readString 方法的唯一区别。
如果读取到结尾仍然没有遇到与 tag
相同的字符,则返回所有剩余的字符,stringIO
对象的 position
属性将被设置为与 length
相同。
readUTF8 方法
- stringIO.readUTF8(n);
假设 stringIO
当前读取位置是 UTF-8
编码的二进制字符串,转换成 UTF-16
编码的字符为 n
个,该方法将返回这个 n
个字符的 UTF-8
编码的字符串,即读取的字符串跟存储的字符串编码是一致的,但是在个数统计上按照 UTF-16
编码方式统计。
执行成功后,stringIO
对象的 position
属性将会相应增加读取到的字符串的 UTF-8
编码的字节数。
如果当前位置到结尾不足 n
个 UTF-16
编码的字符,则读取全部剩余字符并返回,stringIO
对象的 position
属性将被设置为与 length
相同。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- var i, n;
- stringIO.writeUTF16AsUTF8('你好');
- console.log(stringIO.readUTF8(2));
ä½ å¥½
readUTF8AsUTF16 方法
- stringIO.readUTF8AsUTF16(n);
假设 stringIO
当前读取位置是 UTF-8
编码的二进制字符串,转换成 UTF-16
编码的字符为 n
个,该方法将返回这个 n
个字符的 UTF-16
编码的字符串。
执行成功后,stringIO
对象的 position
属性将会相应增加读取到的字符串的 UTF-8
编码的字节数。
如果当前位置到结尾不足 n
个 UTF-16
编码的字符,则读取全部剩余字符并返回,stringIO
对象的 position
属性将被设置为与 length
相同。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- var i, n;
- stringIO.writeUTF16AsUTF8('你好');
- console.log(stringIO.readUTF8AsUTF16(2));
你好
readUTF16AsUTF8 方法
- stringIO.readUTF16AsUTF8(n);
假设 stringIO
当前读取位置是 UTF-16
编码的字符串,读取 n
个字符,并将其转换为 UTF-8
编码的二进制字符串返回。
执行成功后,stringIO
对象的 position
属性将会相应增加读取到的字符串的 UTF-16
编码的字符数。
如果当前位置到结尾不足 n
个 UTF-16
编码的字符,则读取全部剩余字符并返回,stringIO
对象的 position
属性将被设置为与 length
相同。
例如:
- var StringIO = hprose.StringIO;
- var stringIO = new StringIO();
- var i, n;
- stringIO.write('你好');
- console.log(stringIO.readUTF16AsUTF8(2));
ä½ å¥½
take 方法
- stringIO.take();
以字符串形式返回 stringIO
中的所有内容,并清空 stringIO
。
toString 方法
- stringIO.toString();
以字符串形式返回 stringIO
中的所有内容。
clone 方法
- stringIO.clone();
返回当前对象的副本。对新对象的操作,不影响当前对象。
trunc 方法
- stringIO.trunc();
对 stringIO
对象中已经读取的数据部分进行截断处理,只保留未读取的数据,读取偏移量将归零,数据长度将变为剩余数据的长度。如果之前执行过 mark
方法,mark
方法保存的位置信息也会被归零。
原文:
https://github.com/hprose/hprose-js/wiki/%E5%AD%97%E7%AC%A6%E4%B8%B2%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E2%80%94%E2%80%94StringIO