PDA

View Full Version : downloading using URLStream and writing to a file


darth
04-02-2009, 09:28 PM
Hi

I'm trying to make my air app download a file and write it to the disk as it is being downloaded. Here's my code


var stream:URLStream = new URLStream();
stream.addEventListener(ProgressEvent.PROGRESS, startWrite);
stream.addEventListener(Event.COMPLETE, writeComplete);
stream.load(new URLRequest("http://www.myweb.com/test.jpg"));


var file:File = File.documentsDirectory.resolvePath("test.jpg");
if(!file.exists){

}


var fileStream:FileStream = new FileStream();
fileStream.addEventListener(ProgressEvent.PROGRESS , fileprogress)
fileStream.addEventListener(Event.COMPLETE, filecomplete)

var offset:uint = 0

function writeAirFile():void {
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,offset,stream.bytesAvail able);
trace(fileData.length)
fileStream.openAsync(file, FileMode.UPDATE)
//fileStream.open(file, FileMode.UPDATE);
fileStream.writeBytes(fileData,offset,fileData.len gth);
offset+=fileData.length-1
}
function writeComplete(evt:Event){
fileStream.close();
}
function filecomplete(evt:Event):void{
writeAirFile()
}
function startWrite(evt:ProgressEvent):void{
stream.removeEventListener(ProgressEvent.PROGRESS, startWrite)
writeAirFile()
}

after few successful writes I get error -

RangeError: Error #2006: The supplied index is out of bounds.
at flash.filesystem::FileStream/writeBytes()
at filewritetest_fla::MainTimeline/writeAirFile()[filewritetest_fla.MainTimeline::frame1:25]
at filewritetest_fla::MainTimeline/filecomplete()[filewritetest_fla.MainTimeline::frame1:35]


and it doesn't matter if i increment offset by fileData.length or fileData.length-1...

Could anyone explain this, am I trying to do it completely wrong?

kukoc
04-09-2009, 08:28 AM
little complicated.
i dont know why you want directly save piecess of downloaded file to disk.
ProgressEvent.PROGRESS listener in my opinion you should use for example for progressBar

and when whole file is downloaded then using Event.COMPLETE save it at once

check for my proposition

import flash.filesystem.*;

var stream:URLStream = new URLStream();
var file:File = File.documentsDirectory.resolvePath("test.jpg");
var fileStream:FileStream = new FileStream();

stream.addEventListener(ProgressEvent.PROGRESS, progressBar);
stream.addEventListener(Event.COMPLETE, writeComplete);
stream.load(new URLRequest("http://placebo.blox.pl/resource/gg.png"));

function writeComplete(evt:Event){
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,0,stream.bytesAvailable) ;

fileStream.openAsync(file, FileMode.UPDATE)
fileStream.writeBytes(fileData,0,fileData.length);
fileStream.close();

stream.removeEventListener(ProgressEvent.PROGRESS, progressBar);
stream.removeEventListener(Event.COMPLETE, writeComplete);
}

function progressBar(evt:ProgressEvent):void{
// progressBar
}

bdefore
04-22-2009, 09:11 AM
I believe this bounds error you are receiving is due to the limit on the write buffer for writeUTF. I believe the analogous function in Java has a 64kb limit. I'm running into this issue myself and hope to find a solution. My first instinct is that I might have to get dirty with writeBytes(). I'm hoping I don't have to get even uglier and chop my xml up into pieces and use FileMode.UPDATE to write the whole thing.

Anyone else?

darth
09-25-2009, 11:04 AM
I've managed to do like this:


public var fs:FileStream
public var stream:URLStream

private var _output:Boolean = false

public function init(){
stream = new URLStream()

stream.addEventListener(ProgressEvent.PROGRESS, _dlProgressHandler);
stream.addEventListener(Event.COMPLETE, _dlCompleteHandler);
stream.addEventListener(Event.OPEN, _dlStartHandler)

fs = new FileStream();
fs.addEventListener(OutputProgressEvent.OUTPUT_PRO GRESS, _writeProgressHandler)
}
public function startDownload(url:String):void{
fs.openAsync(lfile, FileMode.APPEND)
_output = false
stream.load(new URLRequest(url))
}
public function downloadComplete():void{
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,0,stream.bytesAvailable) ;
fs.writeBytes(fileData,0,fileData.length);
fs.close();
}
public function writeToDisk():void{
_output = false
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,0,stream.bytesAvailable) ;
fs.writeBytes(fileData,0,fileData.length);
}
private function _dlProgressHandler(evt:ProgressEvent):void{
if(_output){
writeToDisk()
}
}
private function _dlCompleteHandler(evt:Event):void{
downloadComplete()
}
private function _dlStartHandler(evt:Event):void{
_output = true
}
private function _writeProgressHandler(evt:OutputProgressEvent):voi d{
_output = true
}