2015-08-03 63 views
9

我正在使用Downloader類從WS2012上的IIS服務器獲取大文件並處理下載進度。帶寬不足時AIR AS3文件下載損壞

它工作正常,但是當客戶端的帶寬過飽和時,Progress事件不會被解除,並且經過一段時間後,下載剛剛停止(Complete事件似乎被觸發?),儘管下載正在未完成,留下客戶一個腐敗的文件。

我找不到如何解決這個問題,甚至什麼策略,我應該承擔這個問題(完成下載並顯示錯誤?等待帶寬可用性,讓我的下一塊字節?)

這裏的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)); 
    } 

} 
+3

我無法解釋行爲只有一些建議來處理它.. .. ..完成下載並顯示錯誤?或者等待帶寬可用性來獲得我的下一個字節?「那麼爲什麼不這樣做呢?如果出現問題,提示**「網絡錯誤導致下載不完整」,此時顯示2個按鈕:「繼續下載」或「保留我所得到的內容」。如果您想恢復,您可以閱讀** [this](http://richapps.de/resumable-downloads-with-air/)**和** [This also](http://mariusht.com/blog/2010/03/10/resumable -file-downloader-simple-air-app /)** ... –

+0

恢復下載似乎對我很好。在文件完成下載之前觸發完整事件時,我可以嘗試多次恢復下載,然後在失敗時間過長時停止。如果有人能夠在答案中詳細說明,我將不勝感激。 –

+1

有一個用於存儲預期文件大小的int變量。現在,當Event Complete觸發時,檢查你的[download]'fileData.length'是否等於'expected_FileSize'。如果小於,則重試直到等於或者足夠好。要從最後一個字節獲得數量,請在請求標題中使用「範圍請求」。它也顯示** [在這個鏈接](https://suzhiyam.wordpress.com/tag/range-header-in-as3/)**如果這對你有幫助。類似於'URLRequestHeader(「range」,「bytes =」+ startPOS +「 - 」+ endPOS);'其中startPOS是'filedata.length + 1',endPos是'expected_FileSize'的數量。 –

回答

1

嘗試一個int變量,用於存儲文件大小預期..

當事件完成火災現在檢查你的[下載] fileData.length等於expected_FileSize。

如果更少,然後重試,直到等於或什麼是好的。要從最後一個字節獲得數量,請在請求標題中使用「範圍請求」。它也顯示在這個鏈接如果這可以幫助你。

類似於 URLRequestHeader("range","bytes="+startPOS+"-"+endPOS);其中startPOS是filedata.length + 1,endPos是expected_FileSize的數量。