18

Flex ベースの AIR アプリケーションでインターネットからファイルをダウンロードする方法を教えてください。

URLをアドレスに設定したファイルを使ってみたのですが、保存しようとするとファイルが存在しませんというエラーが出てしまいました。そして、この問題についてグーグルで助けを求めるのは本当に難しい.

4

5 に答える 5

25

これを実現するには、2 つの API コンボから選択する必要があります。

バージョン 1 は URLLoader と FileStream

このクラスの組み合わせを使用して、URLLoader オブジェクトを介してサーバーからファイルをロードして放送します。これにより、ファイルがメモリにダウンロードされ、ダウンロードが完了すると通知されます。URLLoaderDataFormat.BINARY の dataFormat でダウンロードを開始してください。次に、Filestream オブジェクトを開始し、writeBytes() を使用してディスクに書き込みます。

バージョン 2 は URLStream と FileStream

URLStream は URLLoader と非常に似ていますが、結果を使用する前にファイルが完全にダウンロードされるのを待つ代わりに、ダウンロード中にデータが利用可能になります。この方法は、完全なダウンロードがディスクへの保存を開始するのを待つ必要がないため、大きなファイルに適しています。また、プレーヤーがファイルを渡すと、そのデータに関連するメモリを解放できるため、メモリも節約できます。 . ファイルストリームをまったく同じ方法で使用すると、ファイルがストリームインするときに、ファイルの各チャンクで writeBytes() を実行することになります。

于 2008-12-06T00:05:52.893 に答える
14

seanalltogether の回答を使用し、このクラスを作成してファイルのダウンロードを処理しました。

とてもシンプルです。を作成しvar downloader = new FileDownloader("url", "Local/Path");て呼び出しdownloader.load()、ダウンロードを開始します。

また、完了時、およびダウンロード中のポイントで呼び出される関数の設定もサポートしています。ダウンロードされたバイト数を onProgress 関数に渡します。(ダウンロード前にファイルのサイズを照会する方法がわからなかったため、分数を取得する方法がわかりませんでした)

package com.alex{
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.utils.ByteArray;

public class FileDownloader
{

    // Class to download files from the internet

    // Function called every time data arrives
    //      called with an argument of how much has been downloaded
    public var onProgress :Function = function(t:uint):void{};
    public var onComplete :Function = function():void{};
    public var remotePath :String = "";
    public var localFile :File = null; 

    private var stream :URLStream;
    private var fileAccess :FileStream;

    public function FileDownloader( remotePath :String = "" , localFile :File = null ) {

        this.remotePath = remotePath;
        this.localFile = localFile;
    }

    public function load() :void {
        if( !stream || !stream.connected ) {
            stream = new URLStream();
            fileAccess = new FileStream();

            var requester :URLRequest = new URLRequest( remotePath );
            var currentPosition :uint = 0;
            var downloadCompleteFlag :Boolean = false;

            // Function to call oncomplete, once the download finishes and
            //      all data has been written to disc               
            fileAccess.addEventListener( "outputProgress", function ( result ) :void {
                if( result.bytesPending == 0 && downloadCompleteFlag ) {

                    stream.close();
                    fileAccess.close();
                    onComplete();
                }
            });

            fileAccess.openAsync( localFile, FileMode.WRITE );

            stream.addEventListener( "progress" , function () :void {

                var bytes :ByteArray = new ByteArray();
                var thisStart :uint = currentPosition;
                currentPosition += stream.bytesAvailable;
                // ^^  Makes sure that asyncronicity does not break anything

                stream.readBytes( bytes, thisStart );
                fileAccess.writeBytes( bytes, thisStart );

                onProgress( currentPosition );                      
            });

            stream.addEventListener( "complete", function () :void {
                downloadCompleteFlag = true;
            });

            stream.load( requester );

        } else {
            // Do something unspeakable
        }
    }
}}
于 2009-11-26T20:16:23.663 に答える
7

seanalltogether の 2 番目のアイデアに基づいて構築するために、インターネットからファイルをダウンロードし、ディスクに (デスクトップ上の指定されたファイル名で) 保存する関数を次に示します。

downloadFile: function (url, fileName) {
    var urlStream = new air.URLStream();
    var request = new air.URLRequest(url);
    var fileStream = new air.FileStream();
    // write 50k from the urlstream to the filestream, unless
    // the writeAll flag is true, when you write everything in the buffer
    function writeFile(writeAll) {
        if (urlStream.bytesAvailable > 51200 || writeAll) {
            alert("got some");
            var dataBuffer = new air.ByteArray();
            urlStream.readBytes(dataBuffer, 0, urlStream.bytesAvailable);
            fileStream.writeBytes(dataBuffer, 0, dataBuffer.length);
        }
        // do clean up:
        if (writeAll) {
            alert("done");
            fileStream.close();
            urlStream.close();
            // set up the next download
            setTimeout(this.downloadNextFile.bind(this), 0);
        }
    }

    urlStream.addEventListener(air.Event.COMPLETE, writeFile.bind(this, true));
    urlStream.addEventListener(air.ProgressEvent.PROGRESS, writeFile.bind(this, false));

    var file = air.File.desktopDirectory.resolvePath(fileName);
    fileStream.openAsync(file, air.FileMode.WRITE);

    urlStream.load(request);

}

注: このソリューションでは、Prototype と AIRAliases.js を使用します。

于 2009-01-05T19:33:51.477 に答える
0

flash.net.URLRequestファイルのダウンロードに役立つクラスを確認してください。

于 2008-12-05T11:39:07.300 に答える
0

ファイルをダウンロードするための URLLoader クラスも確認してください。優れた例を次に示します: http://www.adobe.com/devnet/air/flex/articles/exploring_file_capabilities.html

これは、長い時間をかけてファイルをダウンロードするために多くの CPU を必要とする URLStream クラスと比較して、私にとって非常に高速であることがわかりました。

于 2011-05-18T12:53:47.507 に答える