带宽较低时,AIR AS3文件下载已损坏

Tom*_*oup 9 air iis download actionscript-3 windows-server-2012-r2

我正在使用Downloader类从WS2012上的IIS服务器获取大文件并处理下载进度.

它工作正常,但是当客户端的带宽太饱和时,Progress事件不再被触发,并且在一段时间之后下载才停止(完成事件似乎被触发了?),尽管下载未完成,留下客户端有一个损坏的文件.

我无法找到如何解决这个问题,甚至无法解决这个问题的策略(完成下载并显示错误?等待带宽可用性来获取我的下一个字节?)

这是Downloader.as类

public class Downloader extends EventDispatcher
{
    [Event(name="DownloadComplete", type="DownloadEvent")]

    public static var spd:int = 0;
    private var file:File;
    private var fileStream:FileStream;
    private var url:String;
    private var urlStream:URLStream;

    var mc_background:MovieClip;
    var howManyTimes:Number = 3; //How many times per second  the download speed will be traced
    var bytesLoaded:Number = 0; //don't change, necessary for calculation
    var lastTime:int = 0; //don't change, necessary for calculation


    private var waitingForDataToWrite:Boolean = false;

    public function Downloader(s:MovieClip)
    {
        mc_background = s;

        lastTime = getTimer();
        urlStream = new URLStream();

        urlStream.addEventListener(Event.OPEN, onOpenEvent);
        urlStream.addEventListener(ProgressEvent.PROGRESS, onProgressEvent); 
        urlStream.addEventListener(Event.COMPLETE, onCompleteEvent);

        fileStream = new FileStream();
        fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeProgressHandler)

    }

    public function download(formUrl:String, toFile:File):void {
        this.url = formUrl;
        this.file = toFile;
        mc_background.pb.file_txt.text = file.name;
        fileStream.openAsync(file, FileMode.WRITE);
        urlStream.load(new URLRequest(url));
    }

    private function onOpenEvent(event:Event):void {
        waitingForDataToWrite = true;

        dispatchEvent(event.clone());
    }

    private function onProgressEvent(event:ProgressEvent):void {
        var time:int = getTimer();
        if(time - lastTime >= (1000/howManyTimes))
        {
            var kiloBytes:Number = (event.bytesLoaded - bytesLoaded)/1000;
            var timeInSecs:Number = (time - lastTime)/1000;

            var kbsPerSecVal:Number = Math.floor(kiloBytes/timeInSecs);
            trace(kbsPerSecVal + " kbs/s");

            mc_background.pb.speed_txt.text = kbsPerSecVal + " kbs/s";
            bytesLoaded = event.bytesLoaded;
            lastTime = getTimer();
        }
        if(waitingForDataToWrite){
            writeToDisk();
            dispatchEvent(event.clone());
        }
    }

    private function writeToDisk():void {
        var fileData:ByteArray = new ByteArray();
        urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
        fileStream.writeBytes(fileData,0,fileData.length);
        waitingForDataToWrite = false;

        dispatchEvent(new DataEvent(DataEvent.DATA));
    }

    private function writeProgressHandler(evt:OutputProgressEvent):void{
        waitingForDataToWrite = true;
    }

    private function onCompleteEvent(event:Event):void {
        if(urlStream.bytesAvailable>0)
            writeToDisk();
        fileStream.close();

        fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeProgressHandler);

        dispatchEvent(event.clone());
        // dispatch additional DownloadEvent
        dispatchEvent(new DownloadEvent(DownloadEvent.DOWNLOAD_COMPLETE, url, file));
    }

}
Run Code Online (Sandbox Code Playgroud)

VC.*_*One 1

尝试使用 int 变量来存储预期的文件大小。

当事件完成触发时,现在检查您的 [download] fileData.length 是否等于预期文件大小。

如果小于,则重试,直到等于或足够好为止。要获取最后字节数,您可以在请求标头中使用“范围请求”。如果对您有帮助,它也显示在这个链接中。

例如 URLRequestHeader("range","bytes="+startPOS+"-"+endPOS);,startPOS 是 filedata.length+1,endPos 是 Expected_FileSize 数量。