1
votes

I've used examples from here Download a file with Adobe AIR and built app that downloads files from server.

I'll try to explain error by steps.

1) Adobe Air app downloaded xml file from server http://example.com/data/init.xml

2) I've opened it and all ok.

3) Adobe Air app again downloaded the same file from server. Now, if I open it with Notepad it says that init.xml is binary file. If I remove init.xml from disk and try again - the same. init.xml is a binary file. Reopen air app doesn't work.

4) I changed init.xml on server to init123.xml and downloaded it again. init123.xml was opened as normal xml file. If I again download it, then step 3 - init123.xml is a binary file.

Where could be the error?

Thank you.

OS - Windows 7

MD5 of files also changed.

This could be solved it I add random number to the end of url.

urlStream.load(new URLRequest(remoteFile+'?'+Math.random()));

but this

urlStream.load(new URLRequest(remoteFile));

makes file binary if I load it second time.

Source

    private function startDownloading():void
    {
        destFile.nativePath = destDirectory +destFileBase;

        fileStream = new FileStream();            
        fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, outputProgress);
        fileStream.addEventListener(IOErrorEvent.IO_ERROR, fileAccessError);
        fileStream.openAsync(destFile, FileMode.WRITE);

        urlStream = new URLStream();
        urlStream.addEventListener(ProgressEvent.PROGRESS, progress);
        urlStream.addEventListener(Event.COMPLETE, complete);
        urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, urlStreamSecurityError);
        urlStream.addEventListener(IOErrorEvent.IO_ERROR, urlStreamIOError);
        urlStream.load(new URLRequest(remoteFile));
    }

    protected function fileAccessError(event:IOErrorEvent):void
    {
        urlStream.close();
        fileStream.close();

    }

    protected function outputProgress(event:OutputProgressEvent):void
    {
        if(event.bytesPending == 0 && downloadCompleteFlag ) {

        }
    }               

    protected function urlStreamIOError(event:IOErrorEvent):void
    {
        trace('error 2');
    }       

    protected function urlStreamSecurityError(event:SecurityErrorEvent):void
    {
        trace('error 2');
    }

    protected function progress(event:ProgressEvent):void
    {
        var bytes :ByteArray = new ByteArray();
        var thisStart :uint = currentPosition;
        currentPosition += urlStream.bytesAvailable;
        urlStream.readBytes( bytes, thisStart );
        fileStream.writeBytes( bytes, thisStart );

    }       
    protected function complete(event:Event):void
    {
        urlStream.close();
        fileStream.close();
        downloadCompleteFlag = true;
    }
3
Any reason why you use a URLStream instead of an URLLoader? I don't know about Stream related classes but URLLoader lets you specify data format.Exort
Can you provide some code? The code you use to save the file may be useful too.sch
You are not reporting seeing any 'error 2', so I guess there aren't any. Can you trace currentPosition and urlStream.bytesAvailable?sch
Are you sure the destination file is empty when you start downloading?sch
Thank you for answers. It looks like something with cache. Because, with this new URLRequest(remoteFile+'?'+Math.random()) works perfectly. I'll try to experiment on different os and write if i could figure out that problem.Tuco Ramirez

3 Answers

1
votes

Try emptying the destination file. You are probably keeping the previous bytes in init.xml.

0
votes

You are reading into and writing from your ByteArray in the wrong position. You have:

// In "progress" function
urlStream.readBytes( bytes, thisStart );
fileStream.writeBytes( bytes, thisStart );

where thisStart is the current number of bytes available in urlStream.

When using URLStream.readBytes() position refers to the position you want to start reading into bytes. Likewise, the position parameter in FileStream.writeBytes() refers to the position you want to start reading from bytes. Since bytes is reinstantiated every time progress() is called you should always start your reading and writing from a position of 0.

0
votes

From what I can tell the image is being cached which would cause an instant load of the file.
Your code does not deal with that since in your complete function you are not doing fileStream.writeBytes which would make for an empty file.
This is not tested code but you need to do something like this.

protected function progress(event:ProgressEvent):void
{
  var bytes :ByteArray = new ByteArray();
  var thisStart :uint = currentPosition;
  currentPosition += urlStream.bytesAvailable;
  urlStream.readBytes(bytes, thisStart );
  if(bytes.length > 0){
    fileStream.writeBytes( bytes, thisStart );
  }
}       
protected function complete(event:Event):void
{
  progress(event);// call progress to verify data is written
  urlStream.close();
  fileStream.close();
  downloadCompleteFlag = true;
}