Actionscript 3 AdobeAIR。URLStream或FileStream的奇怪错误
我使用了这里的示例,并构建了从服务器下载文件的应用程序 我将尝试按步骤解释错误 1) AdobeAIR应用程序从服务器下载了xml文件 2) 我已经打开了,一切正常 3) AdobeAIR应用程序再次从服务器下载了相同的文件。现在,如果我用记事本打开它,它会说init.xml是二进制文件。如果我从磁盘中删除init.xml并重试-相同。init.xml是一个二进制文件。重新打开air应用程序不起作用 4) 我将服务器上的init.xml改为init123.xml,然后再次下载。init123.xml已作为普通xml文件打开。如果我再次下载它,那么步骤3-init123.xml是一个二进制文件 错误在哪里 多谢各位 操作系统-Windows7 文件的MD5也发生了变化 如果我在url的末尾添加随机数,这个问题就可以解决Actionscript 3 AdobeAIR。URLStream或FileStream的奇怪错误,actionscript-3,apache-flex,air,Actionscript 3,Apache Flex,Air,我使用了这里的示例,并构建了从服务器下载文件的应用程序 我将尝试按步骤解释错误 1) AdobeAIR应用程序从服务器下载了xml文件 2) 我已经打开了,一切正常 3) AdobeAIR应用程序再次从服务器下载了相同的文件。现在,如果我用记事本打开它,它会说init.xml是二进制文件。如果我从磁盘中删除init.xml并重试-相同。init.xml是一个二进制文件。重新打开air应用程序不起作用 4) 我将服务器上的init.xml改为init123.xml,然后再次下载。init123.x
urlStream.load(new URLRequest(remoteFile+'?'+Math.random()));
但是这个
urlStream.load(new URLRequest(remoteFile));
如果我第二次加载文件,则使其成为二进制文件
来源
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;
}
尝试清空目标文件。您可能在init.xml中保留了以前的字节。尝试清空目标文件。您可能将前面的字节保留在init.xml中。您在字节数组中的读写位置错误。你有:
// In "progress" function
urlStream.readBytes( bytes, thisStart );
fileStream.writeBytes( bytes, thisStart );
其中,thisStart
是urlStream
中可用的当前字节数
使用
位置时
指的是要开始读取字节的位置
。同样,中的position
参数指的是要从字节开始读取的位置。由于每次调用progress()
时都会重新实例化bytes
,因此您应该始终从0
的位置开始读写,因为您的字节数组位于错误的位置。你有:
// In "progress" function
urlStream.readBytes( bytes, thisStart );
fileStream.writeBytes( bytes, thisStart );
其中,thisStart
是urlStream
中可用的当前字节数
使用位置时
指的是要开始读取字节的位置
。同样,中的position
参数指的是要从字节开始读取的位置。由于每次调用progress()
时都会重新实例化bytes
,因此您应该始终从0
的位置开始读写,从我可以看出图像正在缓存,这将导致文件的即时加载。
您的代码没有处理这个问题,因为在您的完整函数中,您没有执行将成为空文件的fileStream.writeBytes
。
这不是经过测试的代码,但您需要这样做
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;
}
据我所知,图像正在被缓存,这将导致文件的即时加载。
您的代码没有处理这个问题,因为在您的完整函数中,您没有执行将成为空文件的fileStream.writeBytes
。
这不是经过测试的代码,但您需要这样做
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;
}
您为什么使用URLStream而不是URLLoader?我不知道与流相关的类,但URLLoader允许您指定数据格式。您能提供一些代码吗?你用来保存文件的代码可能也很有用。你没有报告看到任何“错误2”,所以我想没有。能否跟踪currentPosition和urlStream.bytesAvailable?开始下载时是否确定目标文件为空?谢谢您的回答。它看起来像是有缓存的东西。因为,使用这个新的URLRequest(remoteFile+'?'+Math.random())可以完美地工作。我会尝试在不同的操作系统上进行实验,如果我能解决这个问题,我会写一篇文章。你为什么使用URLStream而不是URLLoader?我不知道与流相关的类,但URLLoader允许您指定数据格式。您能提供一些代码吗?你用来保存文件的代码可能也很有用。你没有报告看到任何“错误2”,所以我想没有。能否跟踪currentPosition和urlStream.bytesAvailable?开始下载时是否确定目标文件为空?谢谢您的回答。它看起来像是有缓存的东西。因为,使用这个新的URLRequest(remoteFile+'?'+Math.random())可以完美地工作。我将尝试在不同的操作系统上进行实验,并写下我是否能够解决这个问题。即使我完全删除init.xml,它也将作为二进制数据再次下载。即使我完全删除init.xml,它也将作为二进制数据再次下载。抱歉,我必须-1这个答案。thisStart是他上次迭代的偏移量。他不想一次又一次地重读相同的字节。他想从上次停下来的地方重新开始。从字节数组中读取字节并不会从该数组中删除它们bytearray@The_asMan:“开始读取数据的字节偏移量。默认值为0”。对于第一次迭代,是从0开始。第二次迭代他想从第一次迭代结束的地方开始阅读。第三次迭代,第二次停止。当数据以流方式传输时,它被添加到byteArray中,而不是替换数据。这就是流式传输的好处。您只需要处理到达的新数据。如果他每次都重写文件中的数据,那么按照你的方式来做就行了,这将是多余的,而且速度会慢一些。(我知道这是旧的,但这是为了方便任何人看到它。)按照代码的结构,偏移量应该是0
,而不是thisStart
。让我们假设这个start
是10000,有1000个字节可用。readBytes将在ByteArray中分配11000个字节,并将数据写入最后1000个字节,然后read将读取相同的1000个字节。每次调用this时,都会为thisStart
分配一个较大的ByteArray值。这是一个很好的方式来咀嚼大量的记忆。(刚刚在一些遗留代码中修复了这个问题;-)对不起,我必须-1这个答案。thisStart是他上次迭代的偏移量。他不想