关于ByteArray的clear()的问题

  先看我遇到的问题,有个项目需要通过Socket传输大文件,在SDK4.6之前,因为AS3没有对于Socket写缓冲区的监听事件,也没有描述写缓冲区剩余空间的属性,所以只能以很慢的速度写入数据,如果写入过快就会导致数据包丢失,比如FlexFTP,就是通过Timer,每400毫秒写一次数据,这也算一种解决方式,4.6之前我也是这样做的,但是4.6之后Socket添加了一个bytesPending属性和一个OutputProgressEvent.OUTPUT_PROGRESS事件,可以报告写缓冲区中还剩余多少数据没有写到网络中,因此可以通过这个事件来加快传输速度,以下是我的代码:

private function onOutPutProgress(event:OutputProgressEvent):void{
    if(event.bytesPending == 0){
     if(fileStream.bytesAvailable > 0){
      if(fileStream.bytesAvailable <= 4096){
       trace(byteArray.position, byteArray.length);
       fileStream.readBytes(byteArray, 0, fileStream.bytesAvailable);
       trace("结束");
       trace(byteArray.bytesAvailable);
      }else{
       fileStream.readBytes(byteArray, 0, 4096);
      }
      byteSended += byteArray.bytesAvailable;
      clientSocket.writeBytes(byteArray, 0, byteArray.bytesAvailable);
      clientSocket.flush();
      byteArray.clear();
     }else{
      fileStream.close();
      clientSocket.close();
     }
    }
}

  使用这个事件后,发送速度提高了很多,但是遇到一个问题,我是通过FileStream打开一个文件,然后不断读取这个文件的剩余字节,这里需要用到ByteArray,每次用完,ByteArray都要clear一下,主要是重置position和length
  这里我们先看一下官方的文档

Clears the contents of the byte array and resets the length and position properties to 0.

  意思是clear之后position和length都清零,IDE中鼠标移上去还有一段额外的文字:“显式的调用将清除ByteArray实例所占用的内存空间”。但是实际使用用却发现了一个问题,调用clear之后,ByteArray的长度没有变化,这直接导致最后一次写入时,由于文件的剩余字节数小于4096,但是在写到Socket时还是使用4096写入,所以接收端接收到的文件会稍微大一些,因为这里用的是4096,用户会发现文件大小始终与文件的占用空间一样大。解决办法是在下一次使用前显式调用ByteArray.length = 0。代码如下:

byteArray.length = 0;
fileStream.readBytes(byteArray, 0, fileStream.bytesAvailable);

 

posted @ 2013-03-12 11:47  maga  阅读(713)  评论(0编辑  收藏  举报