3

我正在编写一个 AIR kiosk 应用程序,它每晚都连接到 WordPress 服务器,获取一个包含所有内容路径的 JSON 文件,然后下载该内容并将其保存到 kiosk 硬盘驱动器。

有数百个文件(jpg、png、f4v、xml),其中大多数可以毫无问题地下载/保存。但是,有两个 f4v 文件永远不会完全下载。complete 事件确实被调度了,但是如果我比较 bytesTotal (来自 progress 事件)与 bytesAvailable (来自 complete 事件)它们不匹配;bytesTotal 更大。bytesTotal(来自进度事件)与服务器上的字节匹配。

进度事件中的 bytesLoaded 永远不会增加到与 bytesTotal 匹配的程度,因此我也不能依赖进度事件。这似乎每次都发生在相同的两个视频上。视频不是很大,一个是13MB,一个是46MB。我有较大的视频可以毫无问题地下载。

编辑:重新启动我的计算机后,这两个视频现在完成下载,但我遇到了与 300kb png 文件相同的问题。

如果我将 url 粘贴到 Firefox 中,它会正确下载。我还编写了一个简单的 c# 应用程序来下载文件,它能够毫无问题地下载它们,所以它似乎是 Flash/AIR 的问题。

编辑:这是一个更简单的代码版本,它来自一个测试项目,它是唯一的代码(网址在我们的本地网络上,所以你不能自己下载文件):

package  {

    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.net.URLRequest;
    import flash.net.URLStream;

    [SWF(backgroundColor="#000000", frameRate="24", width="640", height="480")]

    public class Test extends Sprite {

        private var fileSize:Number;
        private var stream : URLStream;
        private var url:String = "http://192.168.150.219/wordpress2/wp-content/uploads/2012/12/John-Butler-clip1.f4v";

        public function Test() {
            if (stage)
                init();
            else
                this.addEventListener(Event.ADDED_TO_STAGE, init);
        }

        private function init(e:Event=null):void {
            this.removeEventListener(Event.ADDED_TO_STAGE, init);
            stream = new URLStream();
            stream.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
            stream.addEventListener(Event.COMPLETE, onLoadComplete);
            stream.load(new URLRequest(url));
        }

        private function onLoadProgress(event:ProgressEvent):void {
            fileSize = event.bytesTotal;
            var percent:Number = event.bytesLoaded / event.bytesTotal * 100;
            trace(percent + "%"); // this never gets to 100%
        }

        private function onLoadComplete(event:Event):void {
            trace("loaded", stream.bytesAvailable, "of", fileSize); 
            // outputs "loaded 13182905 of 13184365"
            // so why is it "complete" when it isn't fully downloaded?
        }
    }
}
4

3 回答 3

2

不要比较bytesAvailablelength而是使用。BytesAvailable 实际上是ByteArray.length - ByteArray.position. 因此,如果 ByteArray 中的位置远离索引 0,则 bytesAvailable 值将减小。长度将始终是数组中的总字节数。

尝试使用长度进行比较,看看这是否有任何区别。我没有时间筛选您的代码以查看您是否在任何时候更改位置(有意或无意;您可以通过多种方式做到这一点),所以这是我现在能提供的最好的。

于 2013-01-24T16:02:31.647 回答
2

如果其他人有和我一样的问题。结果是 AIR 中也存在缓存问题,因此添加到请求中的时间戳可以解决此问题:http: //www.newtonflash.com/blog/as3/prevent-xml-caching-problem/#comment- 43

{
var xmlPath:String="replaceYourXMLPathHere.xml"
var urlReq:URLRequest = new URLRequest(xmlPath+"?time=" + new Date().getTime());
}
于 2013-03-19T15:50:14.720 回答
0

你的答案在你的问题中。

普通 URL(文件)- 对于此服务器,这是一个数据块。一旦服务器交付“数据块”,交付过程就被认为是“完成。在这种情况下,如果文件为 100kb,一旦收到 100kb - Flash 将其视为“完成

URLStream - 对服务器来说这是 [ TWO ] 数据块(非常简单的查看方式)。服务器将首先将CONNECTION提供给流......然后提供STREAM DATA。正如其描述的那样,这是在 Flash 中处理的。

Flash 会将CONNECTION的加载视为“完成”,并且从不检查STREAM数据是否已加载 - 这取决于您的服务器。在任何流中,您实际上应该检查 [load progress] 事件并在数据进入时读取每个字节......然后根据需要进行构造。

于 2013-01-24T21:00:13.043 回答