• 概述
  • 创建 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 提供了 ArrayBufferUint8ArrayTypedArray 可以对二进制数据进行操作。但在低版本浏览器中并没有这些对象,而且这些对象没有自动伸缩性,不方便流式操作,相互转换也比较麻烦。

    为兼容低版本浏览器,并且可以方便操作字符串和二进制数据,hprose for JavaScript 提供了一个 StringIO 对象。StringIO 是一个可自动伸缩的,可流式读写数据的工具类。

    创建 StringIO 对象

    1. new StringIO();
    2. new StringIO(data);
    3. new StringIO(data[, strOffset[, length]]);

    不带参数的构造器创建一个空的 StringIO 对象。空的 StringIO 对象可以进行写操作。

    带 1 个参数的构造器,其中 data 参数是 String 类型的对象,如果是其它类型的对象,将会自动调用其上的 toString() 方法转换为 String 类型的对象。

    带 2-3 个参数的构造器,其中 data 参数为 String 类型的对象,strOffset 为起始偏移量,length 为数据长度。

    方法

    utf8Encode 方法

    1. StringIO.utf8Encode(str);

    该方法的功能是将 UTF-16 编码的字符串 str 转换为 UTF-8 编码的二进制字符串作为结果返回,str 本身不会被修改。

    其中,str 参数为 String 类型的对象。

    如果 str 不是正确的 UTF-16 编码的字符串,会抛出信息为 Malformed string 的异常。

    例如:

    1. var StringIO = hprose.StringIO;
    2. console.log(StringIO.utf8Encode('你好'));
    3. console.log(StringIO.utf8Encode('????'));

    执行结果为:


    1. ä½ å¥½
    2. 🇨🇳🇺🇸

    utf8Decode 方法

    1. StringIO.utf8Decode(binstr);

    该方法的功能是将 UTF-8 编码的二进制字符串 binstr 解码成普通的 UTF-16 编码的 JavaScript 字符串作为结果返回,binstr 本身不会被修改。

    其中,binstr 参数为 String 类型的对象。

    如果 binstr 不是正确的 UTF-8 编码的二进制字符串,会抛出异常。

    例如:

    1. var StringIO = hprose.StringIO;
    2. console.log(StringIO.utf8Decode('ä½ å¥½'));
    3. console.log(StringIO.utf8Decode('🇨🇳🇺🇸'));

    执行结果为:


    1. 你好
    2. ????

    utf8Length 方法

    1. StringIO.utf8Length(str);

    该方法的参数 strUTF-16 编码的字符串,该方法的返回值为将 str 转换为 UTF-8 编码的二进制字符串的长度,str 本身不会被修改。

    其结果与:

    1. StringIO.utf8Encode(str).length

    相同,但是 utf8Length 速度更快。

    例如:

    1. var StringIO = hprose.StringIO;
    2. console.log(StringIO.utf8Length('你好'));
    3. console.log(StringIO.utf8Length('????'));
    4. console.log(StringIO.utf8Encode('????').length);

    执行结果为:


    1. 6
    2. 16
    3. 16

    utf16Length 方法

    1. StringIO.utf16Length(binstr);

    该方法的参数 binstrUTF-8 编码的字符串,该方法的返回值为将 binstr 转换为 UTF-16 编码的字符串的长度,binstr 本身不会被修改。

    其结果与:

    1. StringIO.utf8Decode(binstr).length

    相同,但是 utf16Length 速度更快。例如:

    1. var StringIO = hprose.StringIO;
    2. console.log(StringIO.utf16Length('ä½ å¥½'));
    3. console.log(StringIO.utf16Length('🇨🇳🇺🇸'));
    4. console.log(StringIO.utf8Decode('🇨🇳🇺🇸').length);

    执行结果为:


    1. 2
    2. 8
    3. 8

    isUTF8 方法

    1. StringIO.isUTF8(str);

    该方法的判断参数 str 是否为 UTF-8 编码的二进制字符串,是返回 true,否则返回 false。

    例如:

    1. var StringIO = hprose.StringIO;
    2. console.log(StringIO.isUTF8('hello'));
    3. console.log(StringIO.isUTF8('你好'));
    4. console.log(StringIO.isUTF8('🇨🇳🇺🇸'));

    1. true
    2. false
    3. true

    StringIO.prototype 上的方法

    下面我们用 stringIO 这个变量名来指代 StringIO 的实例对象。

    length 方法

    1. stringIO.length();

    该方法返回当前 stringIO 对象的长度。

    position 方法

    1. stringIO.position();

    该方法返回在对 stringIO 对象进行读取操作时的当前位置。当 position 返回值为 0 时,表示位于数据的开头,当 position 返回值与 length 返回值相同时,表示已没有可读取的数据。

    mark 方法

    1. stringIO.mark();

    保存当前的读写位置。如果对该方法进行多次调用,则只有最后一次保存的读写位置可以被恢复。

    无返回值。

    reset 方法

    1. stringIO.reset();

    恢复由 mark 方法保存的读写位置。

    无返回值。

    clear 方法

    1. stringIO.reset();

    清空 stringIO 对象,并将读写位置归零。

    无返回值。

    writeByte 方法

    1. stringIO.writeByte(byte);

    stringIO 对象的末尾写入一个字节。

    byte 的范围是 0-255 的整数。

    执行成功后,stringIO 对象的 length 属性将会相应加 1。

    无返回值。

    writeInt32BE 方法

    1. stringIO.writeInt32BE(int32);

    stringIO 对象的末尾按照 BigEndian 方式写入一个32位有符号整数(4个字节)。

    int32 的范围是从 -2147483648 到 2147483647,超出范围会抛出 TypeError('value is out of bounds') 的异常。

    执行成功后,stringIO 对象的 length 属性将会相应加 4。如果容量不足,将会自动扩容。

    无返回值。

    writeUInt32BE 方法

    1. stringIO.writeUInt32BE(uint32);

    stringIO 对象的末尾按照 BigEndian 方式写入一个32位无符号整数(4个字节)。

    uint32 的范围是从 0 到 4294967295,超出范围会抛出 TypeError('value is out of bounds') 的异常。

    执行成功后,stringIO 对象的 length 属性将会相应加 4。如果容量不足,将会自动扩容。

    无返回值。

    writeInt32LE 方法

    1. stringIO.writeInt32LE(int32);

    stringIO 对象的末尾按照 LittleEndian 方式写入一个32位有符号整数(4个字节)。

    int32 的范围是从 -2147483648 到 2147483647,超出范围会抛出 TypeError('value is out of bounds') 的异常。

    执行成功后,stringIO 对象的 length 属性将会相应加 4。如果容量不足,将会自动扩容。

    无返回值。

    writeUInt32LE 方法

    1. stringIO.writeUInt32LE(uint32);

    stringIO 对象的末尾按照 LittleEndian 方式写入一个32位无符号整数(4个字节)。

    uint32 的范围是从 0 到 4294967295,超出范围会抛出 TypeError('value is out of bounds') 的异常。

    执行成功后,stringIO 对象的 length 属性将会相应加 4。如果容量不足,将会自动扩容。

    无返回值。

    writeUTF16AsUTF8 方法

    1. stringIO.writeUTF16AsUTF8(str);

    stringIO 对象的末尾以 UTF-8 编码方式写入 UTF-16 编码的字符串 str

    执行成功后,stringIO 对象的 length 属性将会增加相应的长度。

    无返回值。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. stringIO.writeUTF16AsUTF8('你好');
    4. console.log(stringIO.length());
    5. stringIO.writeUTF16AsUTF8('????');
    6. console.log(stringIO.length());

    1. 6
    2. 22

    writeUTF8AsUTF16 方法

    1. stringIO.writeUTF8AsUTF16(binstr);

    stringIO 对象的末尾以 UTF-16 编码方式写入 UTF-8 编码的二进制字符串 binstr

    执行成功后,stringIO 对象的 length 属性将会增加相应的长度。

    无返回值。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. stringIO.writeUTF8AsUTF16('ä½ å¥½');
    4. console.log(stringIO.length());
    5. stringIO.writeUTF8AsUTF16('🇨🇳🇺🇸');
    6. console.log(stringIO.length());
    7. console.log(stringIO.toString());

    1. 2
    2. 10
    3. 你好????

    write 方法

    1. stringIO.write(data);

    stringIO 对象的末尾写入数据 data,对数据 data 不做编解码处理。

    执行成功后,stringIO 对象的 length 属性将会增加相应的长度。

    无返回值。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. stringIO.write('你好');
    4. console.log(stringIO.length());
    5. stringIO.write('????');
    6. console.log(stringIO.length());
    7. stringIO.write(3.14);
    8. console.log(stringIO.length());
    9. console.log(stringIO.toString());

    1. 2
    2. 10
    3. 14
    4. 你好????3.14

    readByte 方法

    1. stringIO.readByte();

    stringIO 对象的当前位置读取一个字节,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 1。

    如果当前位置已在结尾,则返回 -1。

    注意:该方法仅对二进制编码的数据有效。如果内容中包含有 UTF-16 编码的字符串,返回的将是 UTF-16 的字符的数字编码,该编码可能会大于 255。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. var i, n;
    4. stringIO.writeUTF16AsUTF8('你好');
    5. for (i = 0, n = stringIO.length(); i < n; i++) {
    6. console.log(stringIO.readByte());
    7. }
    8. console.log('----');
    9. stringIO.write('你好');
    10. for (i = n, n = stringIO.length(); i < n; i++) {
    11. console.log(stringIO.readByte());
    12. }
    13. console.log('----');
    14. console.log(stringIO.readByte());

    1. 228
    2. 189
    3. 160
    4. 229
    5. 165
    6. 189
    7. ----
    8. 20320
    9. 22909
    10. ----
    11. -1

    readChar 方法

    1. stringIO.readChar();

    stringIO 对象的当前位置读取一个字符,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 1。

    如果当前位置已在结尾,则返回 ''。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. var i, n;
    4. stringIO.writeUTF16AsUTF8('你好');
    5. for (i = 0, n = stringIO.length(); i < n; i++) {
    6. console.log(stringIO.readChar());
    7. }
    8. console.log('----');
    9. stringIO.write('你好');
    10. for (i = n, n = stringIO.length(); i < n; i++) {
    11. console.log(stringIO.readChar());
    12. }

    1. ä
    2. ½
    3. å
    4. ¥
    5. ½
    6. ----

    readInt32BE 方法

    1. stringIO.readInt32BE();

    stringIO 对象的当前位置读取 4 个字节,按照 BigEndian 编码方式转换为一个 32 位有符号整型数,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 4。

    如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF') 异常。

    readUInt32BE 方法

    1. stringIO.readUInt32BE();

    stringIO 对象的当前位置读取 4 个字节,按照 BigEndian 编码方式转换为一个 32 位无符号整型数,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 4。

    如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF') 异常。

    readInt32LE 方法

    1. stringIO.readInt32LE();

    stringIO 对象的当前位置读取 4 个字节,按照 LittleEndian 编码方式转换为一个 32 位有符号整型数,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 4。

    如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF') 异常。

    readUInt32LE 方法

    1. stringIO.readUInt32LE();

    stringIO 对象的当前位置读取 4 个字节,按照 LittleEndian 编码方式转换为一个 32 位无符号整型数,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 4。

    如果当前位置到结尾不足 4 个字节,则抛出 Error('EOF') 异常。

    read 方法

    1. stringIO.read(n);

    stringIO 对象的当前位置读取长度为 n 的字符串,并返回。

    执行成功后,stringIO 对象的 position 属性将会相应加 n

    如果当前位置到结尾不足 n 个字符,则读取全部剩余字符并返回,stringIO 对象的 position 属性将被设置为与 length 相同。

    skip 方法

    1. stringIO.skip(n);

    stringIO 对象的当前位置略过 n 个字符,并返回实际略过的字符数。

    执行成功后,stringIO 对象的 position 属性将会相应加 n。

    如果当前位置到结尾不足 n 个字符,则略过全部剩余字符并返回略过的剩余字符数,stringIO 对象的 position 属性将被设置为与 length 相同。

    readString 方法

    1. stringIO.readString(tag);

    stringIO 对象的当前位置开始读取,直到遇到与 tag 相同的字符为止,并以字符串返回。

    执行成功后,stringIO 对象的 position 属性将会相应增加读取到的字符数。

    读取到的字符串中包含有最后的 tag 字符。

    如果读取到结尾仍然没有遇到与 tag 相同的字符,则返回所有剩余的字符,stringIO 对象的 position 属性将被设置为与 length 相同。

    readUntil 方法

    1. stringIO.readUntil(tag);

    stringIO 对象的当前位置开始读取,直到遇到与 tag 相同的字节为止,并以字符串返回。

    执行成功后,stringIO 对象的 position 属性将会相应增加读取到的字符数。

    读取到的数据中不包含有最后的 tag 字符。但在位置计算上会算上 tag 字符。这是它与 readString 方法的唯一区别。

    如果读取到结尾仍然没有遇到与 tag 相同的字符,则返回所有剩余的字符,stringIO 对象的 position 属性将被设置为与 length 相同。

    readUTF8 方法

    1. stringIO.readUTF8(n);

    假设 stringIO 当前读取位置是 UTF-8 编码的二进制字符串,转换成 UTF-16 编码的字符为 n 个,该方法将返回这个 n 个字符的 UTF-8 编码的字符串,即读取的字符串跟存储的字符串编码是一致的,但是在个数统计上按照 UTF-16 编码方式统计。

    执行成功后,stringIO 对象的 position 属性将会相应增加读取到的字符串的 UTF-8 编码的字节数。

    如果当前位置到结尾不足 nUTF-16 编码的字符,则读取全部剩余字符并返回,stringIO 对象的 position 属性将被设置为与 length 相同。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. var i, n;
    4. stringIO.writeUTF16AsUTF8('你好');
    5. console.log(stringIO.readUTF8(2));

    1. ä½ å¥½

    readUTF8AsUTF16 方法

    1. stringIO.readUTF8AsUTF16(n);

    假设 stringIO 当前读取位置是 UTF-8 编码的二进制字符串,转换成 UTF-16 编码的字符为 n 个,该方法将返回这个 n 个字符的 UTF-16 编码的字符串。

    执行成功后,stringIO 对象的 position 属性将会相应增加读取到的字符串的 UTF-8 编码的字节数。

    如果当前位置到结尾不足 nUTF-16 编码的字符,则读取全部剩余字符并返回,stringIO 对象的 position 属性将被设置为与 length 相同。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. var i, n;
    4. stringIO.writeUTF16AsUTF8('你好');
    5. console.log(stringIO.readUTF8AsUTF16(2));

    1. 你好

    readUTF16AsUTF8 方法

    1. stringIO.readUTF16AsUTF8(n);

    假设 stringIO 当前读取位置是 UTF-16 编码的字符串,读取 n 个字符,并将其转换为 UTF-8 编码的二进制字符串返回。

    执行成功后,stringIO 对象的 position 属性将会相应增加读取到的字符串的 UTF-16 编码的字符数。

    如果当前位置到结尾不足 nUTF-16 编码的字符,则读取全部剩余字符并返回,stringIO 对象的 position 属性将被设置为与 length 相同。

    例如:

    1. var StringIO = hprose.StringIO;
    2. var stringIO = new StringIO();
    3. var i, n;
    4. stringIO.write('你好');
    5. console.log(stringIO.readUTF16AsUTF8(2));

    1. ä½ å¥½

    take 方法

    1. stringIO.take();

    以字符串形式返回 stringIO 中的所有内容,并清空 stringIO

    toString 方法

    1. stringIO.toString();

    以字符串形式返回 stringIO 中的所有内容。

    clone 方法

    1. stringIO.clone();

    返回当前对象的副本。对新对象的操作,不影响当前对象。

    trunc 方法

    1. 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