好吧,目前我的 SWF 命中了一个 php 文件,该文件将查找我指定的所有文件,将它们的大小加在一起,然后将它们的组合大小作为一个数字返回。然后,我将这个数字与 ProgressEvent 侦听器一起使用,以确定网站特定部分的当前文件下载百分比。

很简单吧?现在,使用该 PHP 文件是不可能的,我正在尝试在 SWF 内部执行所有操作,而不是让它通过外部脚本来获取我需要的数字。

在开始将文件加载到闪存之前,有什么好的方法可以获取文件的大小吗?我确实需要预加载器是 0 到 100% 的预加载器,因此我需要在实际开始之前下载的总字节数。

我的一个想法是遍历保存文件 URL 的数组,开始加载它们,getTotalBytes 而不显示任何加载,在第一个刻度上终止加载,将所有这些总字节数相加,然后开始实际的下载过程。这种方法看起来非常丑陋,而且会浪费大量时间,因为每次用户点击网站上的预加载器时,可能需要一两秒钟的时间来运行所有文件,找到它们的总数,然后真正开始下载。

有没有更好的解决方案来解决这个问题,而无需超出闪存来获取这些文件的大小?

有帮助吗?

解决方案

您可以向服务器发出 HTTP HEAD 请求以获取文件。这将返回标头信息(包括文件大小),但不返回实际文件。然后您可以发出 GET 请求来加载文件。

http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

(查看第 9.4 节 HEAD)

我可能会做的是一个两层进度条(有 2 个进度条)。一个显示总体进度(0 到 100%),另一个显示每个文件的进度(下载每个文件时)。

这样,只要您知道要加载的文件数量,您就可以完成总进度,而无需首先访问服务器来获取文件大小。

迈克·钱伯斯

mesh@adobe.com

其他提示

Mike Chamber 的想法会对您有所帮助,但它仍然比使用服务器端的东西慢,因为无论如何您都必须对每个文件发出请求。它本质上与您自己所说的相同,但是当您明确要求标头时,它会稍微快一些。使用 Socket 来执行请求:

var socket : Socket = new Socket( );
socket.addEventListener( Event.CONNECT, connectHandler );
socket.addEventListener( ProgressEvent.SOCKET_DATA, dataHandler );
socket.connect( "yourserver.com", 80 );

function connectHandler( event : Event ) : void {
    var headers : String = "HEAD yourfilename.ext http/1.1\r\n";
    headers += "Host: yourserver.com\r\n";
    headers += "\r\n\r\n";
    socket.writeUTFBytes( headers );
    socket.flush( );
}

function dataHandler( event : ProgressEvent ) : void {
    trace( "Received headers\n" );
    trace( socket.readUTF( socket.bytesAvailable ) );
}

如果绝对有必要控制文件的加载方式,那么我相信 Mike Chambers 提出的发出 HTTP HEAD 请求的建议是正确的选择。

但是,除非有充分的理由不这样做,否则我只需开始立即加载所有文件,并从每个文件的 getBytesTotal 方法获取文件大小。由于 Flash 从浏览器获取其网络堆栈,因此实际同时加载的文件数量将符合(用户可定义的)浏览器设置。

以下仅用于示例目的。在实际情况中,我不会使用 Timer,我会使用一个数组或 XML 对象来使用 for 循环进行迭代,无论它工作得很好,而且基本上一旦到达循环末尾(例如if(i == (length - 1)) 让它调用开始实际预加载的功能,现在我们已经有了总数。现在我们再次迭代数组或 XML 对象,但这次我们仅在每个资源加载后执行此操作,而不是在 for 循环中执行。然后,该异步方法可以坐在那里比较它已加载的数据量,并将其除以之前找到的总数,从而得出百分比。

var totalBytes:Number = 0;

var loader:Loader = new Loader();
var request:URLRequest = new URLRequest();
request.url = 'badfish.jpg';

var timer:Timer = new Timer(200);
timer.addEventListener(TimerEvent.TIMER, onTimer);

function onTimer(e:TimerEvent)
{
    loader.load(request);
    loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
}
function onProgress(e:ProgressEvent):void
{
    totalBytes+=e.bytesTotal;
    trace(e.bytesTotal,totalBytes);
    loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
}

timer.start();
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top