ByteArray是一种有用的对象
他有3个值得注意的属性
position 及 length,endian
ByteArray 有二种操作
一种是Read系列,主要是将从position开始的,返回某种类型长度或指定长度的缓冲,返回结果会做根据字节顺序一些处理,同时postion会自动移到读取缓冲的终点。
二是Write系列,也是从position开始,写入某种类型长度或指定长度的数据(必要时会根据字节顺序作处理),同时position会自增。
要注意的有几点
1)字节顺序
var b:ByteArray= new ByteArray;
b.endian=flash.utils.Endian.BIG_ENDIAN;
b.writeShort(0x1234);
b.position=0;
trace(b.readByte());//=0x12,如果b.endian=flash.utils.LITTLE_ENDIAN,则是0x34
2)readBytes
ByteArray.readBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void
Reads the number of data bytes, specified by the length parameter, from the byte stream.
如
var b:ByteArray= new ByteArray;
var a:ByteArray= new ByteArray;
..
b.ReadBytes(a,o,l);
这时从b的角度来考虑,b是从b.position开始读取b的内容的。
从a的角度来看,a被写的数据是存放在[o,o+l)这段空间的,这时不关心a的position在何处。
如果a的长度原来不够,则会自动增长到o+l长度。
3)writeBytes
public function writeBytes(bytes:ByteArray, offset:uint = 0, length:uint = 0):void
var b:ByteArray= new ByteArray;
var a:ByteArray= new ByteArray;
...
b.writeBytes(a,o,l);
表示从b.postion 开始写入从a的o处开始l 长度的缓冲到b
4) 关于字符集的问题
ByteArray在处理utf-8及普通字符集都没有太大问题(通过read/writeUTF/MultiByte)
但在处理utf-16时有点小麻烦。
也就说,如果ByteArray存放的是utf-16则有些问题。
flex 自己的文档 “Supported Character Sets” 有这么一行:Unicode (Big-Endian) unicodeFFFE ,也就是说 0xFFFE flex当成大端的BOM,然而恰恰相反,这似乎应该是小端BOM吧。
所以当byteArray存放的是ucs-2时,即无论是大端还是小端,或者你怎么设置都不能正确得到字符串。晕啊。
这太郁闷了,当有BOM存在时,经过代码验证,flex是忽略ByteArray的endian设置的---只要有BOM存在(这是有道理的,因为bom决定了字节顺序)。
我写了一个小小的flex页面(页面及代码见文章最后),专门来测试,试了大把的charset 。最后的结果是让我对使用readMultiByte读取ucs-2(utf16-be or utf16-le)的缓冲不抱任何希望。
因此凡是utf-16编码的ByteArray得通过另外的方法来取得--而且有比较简单的方法(运气啊!是运气,还是因为上帝在这里关上门,就会在另一面打开一扇窗?)
ByteArray中缓冲区的数据要符合二个条件就可以读出
- 必须得有BOM
- BOM之后的数据流字节顺序与BOM是一致的
这样就可以通过ByteArray.toString()得到 String了!
小小代码例子:
var s:String = "123中国";
var b:ByteArray= new ByteArray;
b.writeByte(0xFF);
b.writeByte(0xFE);
b.endian=Endian.LITTLE_ENDIAN; //与上面的BOM对应起来
for ( var i:int = 0 ; i <s.length ; ++i )
{
buff.writeShort( s.charCodeAt( i ));
}var news:String = b.toString();
trace(news);
// or
var s:String = "123中国";
var b:ByteArray= new ByteArray;
b.writeByte(0xFE);
b.writeByte(0xFF);
b.endian=Endian.BIG_ENDIAN; //与上面的BOM对应起来
for ( var i:int = 0 ; i <s.length ; ++i )
{
buff.writeShort( s.charCodeAt( i ));
}var news:String = b.toString();
trace(news);
我测试的flash程序所在
http://chensheng.net/p/test-bytearray/
源代码点右键可以看到,utf-16字符串与byteArray之间的相互转换
btw:这好象是一个bug
请参见:http://bugs.adobe.com/jira/browse/FP-716
呵呵,这么说来,许多中文论坛上关于 Flex 中文乱码 的麻烦是有原因的,我这才是解决之首。