views:

1040

answers:

6

Im looking for a simple way to find the file sizes of the files i planning on loading without loading them yet. I'm basically making a batch of files that needs to be loaded and it would be very useful if I could determine on beforehand how big the total load is going to be.

the Loader object in flash has a totalBytes property, but that will only return a value when you are already loading a file.

+1  A: 

There is no way to getting the size of a file before from Actionscript 3. A easy solution would be to add a small script to the server which scans for all files and returns their names and their size to the swf (as JSON or XML or whatever).

Hippo
A: 

There is no way to do this in ActionScript. You'll need some server side code to do this. You could create a method that takes a filename and returns the total bytes.

Christophe Herreman
A: 

I don't know how you would do this with actionscript (I'm no Guru) but my first guess would be to use a PHP script (or any other scripting language of your choice) to get the file sizes and return the values.

gargantaun
A: 

Another (probably overkill) way would be to create something that simply asks the server for the headers of the file (including the filesize). The same could be achieved by simply starting to download the file and closing the stream when you have the filesize (should be pretty fast) or having (as suggested before) some other way of asking the server for the size for the file (useful if you're loading multiple files and need to know the filesize before loading)

Antti
+1  A: 

By loaded, do you mean entirely loaded, or with no load call? If a load call is acceptable, the following could be useful. The progress event gives the incoming data's Total size on the first fire. We merely let a given progress event fire, take the total value of the current loading item and add that to our own _total variable; We continue this until our dataprovider (array, xml, etc) is empty. by the end you have the sum of all your assets totals.

package
{
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.events.Event;
    import flash.events.ProgressEvent;
    import flash.URLLoader;
    import flash.URLRequest;

    public class ExampleDocumentClass extends Sprite
    {
        private var _urlLoader:URLLoader;
        private var _loader:Loader;
        private var _request:URLRequest;
        private var _total:Number;
        private var _array:Array;

        public function ExampleDocumentClass():void
        {
            if(stage) _init;
            else addEventListener(Event.ADDED_TO_STAGE, _init);
        }
        private function _init(e:Event = null):void
        {
            _array = [{type:"nonDisplay", path:"path/to/file"},{type:"display", path:"path/to/file"}];
            _urlRequest = new URLRequest();

            //Non display asset
             _urlLoader = new URLLoader();
            _urlLoader.addEventListener(ProgressEvent.PROGRESS, _onProgress);

            //Display asset
            _loader = new Loader();

            loadAsset();
        }
        private function loadAsset():void
        {
            if(_array.length > 0)
            {
                var pObj:Object = _array[0];
                if(pObj.type == "nonDisplay")
                {
                    loadNonDisplayAsset(pObj.path);
                }
                else
                {
                    loadDisplayAsset(pObj.path);
                }
                //Remove this item from the array;
                _array.shift();
            }
        }
        private function loadNonDisplayAsset(pAsset:String):void
        {
            _urlRequest.url = pAsset;
            _urlLoader.load(_urlRequest);
        }
        private function loadDisplayAsset(pAsset:String):void
        {
            _urlRequest.url = pAsset;
            _loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, _onProgress);
            _loader.load(_urlRequest);
        }
        private function _onProgress(e:ProgressEvent):void
        {
            _total += e.bytesTotal;
            _loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS, _onProgress);
            _urlLoader.removeEventListener(ProgressEvent.PROGRESS, _onProgress);
        }
    }
}

So we load an asset just long enough to append its Size total, to our own _total variable and then we call the next item in the array and append its total until the data provider is empty. Obviously this could be done with XML, or however you wish, an array is just what i used for the exercise.

Brian Hodge
hodgedev.com blog.hodgedev.com

Brian Hodge
Sounds like a fairly good solution. Not as clean as I would hope it could be (avoiding loadcalls). But this will work. Thanks!
Kasper
URLLoader and Loader are necessary to access the data you required and as long as your careful to clean and/or reuse your listeners, removing the final, I see nothing wrong with the implementation. Thanks for the good question. Good luck!
Brian Hodge
A: 

This post is quite old, but it lead me to the right path in the end, so hopefully this will help someone, somewhere...

I have experimented with the method provided by Brian Hodge, as well as another method in which I sent variables (folder locations as strings from XML) to PHP in order to get the combined size of all files within a particular folder and return the data to Flash.

One major problem I encountered on my journey to preloading paradise was that Flash Player seems to produce inconsistent results with regard to file size! Even if I loaded exactly the same files twice Flash would tell me they were different sizes... sometimes.

This also caused problems with the alternate (PHP) method, since the PHP script would produce (seemingly) accurate file size results that were inconsistent with those produced by Flash, causing my loader to go to 85% or 128%, dependant on caching and Flash's mood :/

I scrapped both methods in favour of a nice class called bulk-loader, which allows for queued loading and progress tracking of multiple items, and much more :D

just be aware that it will increase your swf file size significantly... how ironic

munkychop