Babu
Babu

Reputation: 442

How to write a XML file which is already opened using URLLoader in as3?

I have an XML which is inside the application directory I need to modify that XML file.First i load that XML with URLLoder using the below codes and then modify the XML and when i try to write the XML file in same location with the same name it is not working.If i change the file name to something else then it is working fine.So my problem is that i want to modify the XML file and save it in the same location with the same name.How can i achieve this?

        private var ldr:URLLoader;
        private function changeAppID():void
        {
            var FolderPath = File.applicationDirectory.nativePath+"\\assets"
            var tempFile:File = File.userDirectory.resolvePath(FolderPath);

            if(tempFile.exists)
            {
                ldr = new URLLoader();
                ldr.addEventListener(Event.COMPLETE, onLoad);
                ldr.load(new URLRequest(FolderPath + "\\data\\application.xml"));
            }
            else
            {
                trace("Assets Folder Does Not Exists !"); 
            }
        }


        protected function onLoad(event:Event):void
        {
            var bytearray:ByteArray = new ByteArray();
            var loadedXml:XML = new XML((event.target).data);
            loadedXml.children()[0] = "Riaxe"+getCurrentTime();
            bytearray = getXMLToByteArray( loadedXml );

            var path:String = File.applicationDirectory.nativePath + "\\assets\\data\\application.xml";
            var file:File = new File(path);
            var fileStream:FileStream = new FileStream();
            fileStream.open( file, FileMode.WRITE );
            fileStream.writeBytes( bytearray , 0 , bytearray.length );
            fileStream.close();
        }

Upvotes: 0

Views: 217

Answers (3)

BotMaster
BotMaster

Reputation: 2223

The problem is that the application directory is in a sandbox and files in there are not supposed to be modified in any way. This is true for any technology even though there are some known hacky work arounds.

The solution is to always use the application storage directory that is always available and meant for that very purpose. Is you do not use that directory then you are the one creating your own problem by trying to work within a folder that is by definition protected and sandboxed against modifications of any kind.

If you insist on this then you might find some work arounds like I said but you'll never have any guaranties that your work around will work on every OS or after any future OS updates.

Your app might break after a OS update or already on some OS with a higher security setting only because of your educated decision to break the rules.

Once again I recommend using the application storage directory instead that is specially sandboxed for that purpose and that is the only correct answer in this case.

Upvotes: 0

Aaron Beall
Aaron Beall

Reputation: 52153

Why are you opening the file with a URLRequest instead of a FileStream? You can use FileMode.UPDATE to do both things synchronously.

For example:

var assetsDir:File = File.applicationDirectory.resolvePath("assets");
var applicationFile:File = assetsDir.resolvePath("data/application.xml");

// open the file for read/write
var fileStream:FileStream = new FileStream();
fileStream.open(applicationFile, FileMode.UPDATE);

// load the XML and change it
var xml:XML = XML(fileStream.readUTFBytes(fileStream.bytesAvailable));
xml.id = (Math.random() * int.MAX_VALUE).toString(36);
xml.date = new Date().toDateString();

// replace contents of file with modified XML
fileStream.position = 0;
fileStream.truncate();
fileStream.writeUTFBytes(xml.toXMLString());
fileStream.close();

Note:

  • You're checking for tempFile.exists but not doing anything with it. I'm not sure what you are trying to do there, so I omitted it.
  • You can read and write XML strings directly to files using readUTFBytes() and writeUTFBytes().
  • It's not a good practice to build native file path URLs using string literals like nativePath + "\\assets", use resolvePath instead (see docs).
  • I'm not really sure what you are trying to do with application.xml. It looks a bit like you are trying to allow multiple instances of your app to be started, but applicationDirectory/assets/data/application.xml is not the right path as far as I know, that's where you might include your own XML file. Maybe you're making a AIR app builder utility?

Upvotes: 0

akmozo
akmozo

Reputation: 9839

To avoid that problem, you have to open your file asynchronously using FileStream.openAsync(), so your code can be like this :

var fileStream:FileStream = new FileStream();
    fileStream.openAsync(file, FileMode.WRITE);

    // here you can write your XML content as string, you dont need a ByteArray object
    fileStream.writeUTFBytes(loadedXml.toXMLString());
    fileStream.close();

Hope that can help.

Upvotes: 2

Related Questions