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));
}
}
我無法解釋行爲只有一些建議來處理它.. .. ..完成下載並顯示錯誤?或者等待帶寬可用性來獲得我的下一個字節?「那麼爲什麼不這樣做呢?如果出現問題,提示**「網絡錯誤導致下載不完整」,此時顯示2個按鈕:「繼續下載」或「保留我所得到的內容」。如果您想恢復,您可以閱讀** [this](http://richapps.de/resumable-downloads-with-air/)**和** [This also](http://mariusht.com/blog/2010/03/10/resumable -file-downloader-simple-air-app /)** ... –
恢復下載似乎對我很好。在文件完成下載之前觸發完整事件時,我可以嘗試多次恢復下載,然後在失敗時間過長時停止。如果有人能夠在答案中詳細說明,我將不勝感激。 –
有一個用於存儲預期文件大小的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'的數量。 –