【问题标题】:How to write a XML file which is already opened using URLLoader in as3?如何编写一个已经在 as3 中使用 URLLoader 打开的 XML 文件?
【发布时间】:2016-07-29 09:24:52
【问题描述】:

我在应用程序目录中有一个 XML,我需要修改该 XML 文件。首先,我使用以下代码使用 URLLoder 加载该 XML,然后修改 XML,当我尝试将 XML 文件写入同一位置时同名它不起作用。如果我将文件名更改为其他名称,那么它工作正常。所以我的问题是我想修改 XML 文件并将其保存在同名的相同位置。我怎么能实现这个?

        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();
        }

【问题讨论】:

    标签: xml actionscript-3 xml-parsing air flex4.5


    【解决方案1】:

    为了避免这个问题,你必须使用FileStream.openAsync()异步打开你的文件,所以你的代码可以是这样的:

    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();
    

    希望能有所帮助。

    【讨论】:

      【解决方案2】:

      您为什么用URLRequest 而不是FileStream 打开文件?您可以使用FileMode.UPDATE 同步执行这两项操作。

      例如:

      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();
      

      注意:

      • 您正在检查tempFile.exists,但没有对它做任何事情。我不确定你想在那里做什么,所以我省略了它。
      • 您可以使用readUTFBytes()writeUTFBytes() 直接读取XML 字符串并将其写入文件。
      • 使用nativePath + "\\assets" 等字符串文字构建本机文件路径URL 不是一个好习惯,请改用resolvePath (see docs)。
      • 我不太确定你想用application.xml 做什么。看起来有点像您正在尝试allow multiple instances of your app to be started,但据我所知applicationDirectory/assets/data/application.xml 不是正确的路径,您可能会在其中包含您自己的 XML 文件。也许您正在制作 AIR 应用程序构建器实用程序?

      【讨论】:

        【解决方案3】:

        问题是应用程序目录位于沙箱中,不应该以任何方式修改其中的文件。即使有一些已知的 hacky 变通方法,任何技术都是如此。

        解决方案是始终使用始终可用且专门用于此目的的应用程序存储目录。如果您不使用该目录,那么您是通过尝试在定义上受保护并沙盒化以防止任何形式的修改的文件夹中工作来创建自己的问题的人。

        如果您坚持这一点,那么您可能会像我说的那样找到一些变通方法,但您永远无法保证您的变通方法适用于每个操作系统或在任何未来的操作系统更新之后。

        您的应用可能会在操作系统更新后或已经在具有更高安全设置的某些操作系统上崩溃,这仅仅是因为您做出了违反规则的明智决定。

        我再次建议使用应用程序存储目录,而不是为此目的专门设置沙盒,这是在这种情况下唯一正确的答案。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-09-07
          • 2016-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-09
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多