gpt4 book ai didi

actionscript-3 - AIR (As3) - 通过 iPad 应用程序下载大文件

转载 作者:行者123 更新时间:2023-12-02 05:16:15 25 4
gpt4 key购买 nike

首先我要说明的是,我不能发布源代码,因为项目很大。我正在尝试在 iPad 设备上下载一个大文件 (500+ MB)。最初我尝试使用 URLLoader,但后来我意识到 iPad 设备的内存资源非常有限。比我认为 URLStream 将分块下载文件,而使用 FileStream 我可以将这些 block 保存在设备上(如 AS3: URLStream saving files to desktop? ),但我错了,当我尝试下载大文件时设备崩溃,因为 RAM设备的容量是不够的(更准确地说,这变得太大了:System.privateMemory)有谁知道如何分块下载文件,是否可以不使用“套接字连接”?

提前致谢。

编辑:这是我使用的代码(注释行是 FileStream 仅在文件下载后才关闭的版本。



package components.streamDownloader
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.OutputProgressEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.net.URLRequest;
import flash.net.URLStream;
import flash.system.System;
import flash.utils.ByteArray;


/**
*
*/
public class StreamDownloader extends EventDispatcher
{

[Event(name="DownloadComplete", type="com.tatstyappz.net.DownloadEvent")]

[Event(name="Error", type="com.tatstyappz.net.DownloadEvent")]


//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------

public function StreamDownloader()
{

}


//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------

private var file:File;

//private var fileStream:FileStream;

private var urlRequest:URLRequest;

private var urlStream:URLStream;

private var waitingForDataToWrite:Boolean = false;


//--------------------------------------------------------------------------
//
// API
//
//--------------------------------------------------------------------------

public function download(urlRequest:URLRequest, file:File):void {


init();

this.urlRequest = urlRequest;
this.file = file;
//fileStream.open(file, FileMode.WRITE);
urlStream.load(urlRequest);
}


//--------------------------------------------------------------------------
//
// Event handlers
//
//--------------------------------------------------------------------------

//----------------------------------
// urlStream events
//----------------------------------

protected function urlStream_openHandler(event:Event):void
{
waitingForDataToWrite = false;
dispatchEvent(event.clone());
}

protected function urlStream_progressHandler(event:ProgressEvent):void
{


trace("MEMORY:", System.totalMemoryNumber / 1024 / 1024, "MEMORY P:", System.privateMemory / 1024 / 1024, "FREE MEMORY:", System.freeMemory / 1024 / 1024, "PROGRESS:", event.bytesLoaded / event.bytesTotal );




if(waitingForDataToWrite){
writeToDisk();
}
}

protected function urlStream_completeHandler(event:Event):void
{
if(urlStream.bytesAvailable > 0)
{
writeToDisk();
}
//fileStream.close();

destory();

dispatchEvent(event.clone());

// dispatch additional DownloadEvent
dispatchEvent(new StreamDownloadEvent(StreamDownloadEvent.DOWNLOAD_COMPLETE, urlRequest, file));
}

protected function urlStream_securityErrorHandler(event:SecurityErrorEvent):void
{
dispatchEvent(new StreamDownloadEvent(StreamDownloadEvent.ERROR, urlRequest, file, event.errorID.toString()));
destory();
}

protected function urlStream_ioErrorHandler(event:IOErrorEvent):void
{
dispatchEvent(new StreamDownloadEvent(StreamDownloadEvent.ERROR, urlRequest, file, event.errorID.toString()));
destory();
}


//----------------------------------
// fileStream events
//----------------------------------

protected function fileStream_outputProgressHandler(event:OutputProgressEvent):void
{
waitingForDataToWrite = true;
}

protected function fileStream_ioErrorHandler(event:IOErrorEvent):void
{
dispatchEvent(new StreamDownloadEvent(StreamDownloadEvent.ERROR, urlRequest, file, event.errorID.toString()));
destory();
}


//--------------------------------------------------------------------------
//
// Utils
//
//--------------------------------------------------------------------------

private function init():void
{
urlStream = new URLStream();
//fileStream = new FileStream();

urlStream.addEventListener(Event.OPEN, urlStream_openHandler);
urlStream.addEventListener(ProgressEvent.PROGRESS, urlStream_progressHandler);
urlStream.addEventListener(Event.COMPLETE, urlStream_completeHandler);
urlStream.addEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
urlStream.addEventListener(SecurityErrorEvent.SECURITY_ERROR, urlStream_securityErrorHandler);

//fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, fileStream_outputProgressHandler)
//fileStream.addEventListener(IOErrorEvent.IO_ERROR, fileStream_ioErrorHandler);
}

private function destory():void
{
urlStream.removeEventListener(Event.OPEN, urlStream_openHandler);
urlStream.removeEventListener(ProgressEvent.PROGRESS, urlStream_progressHandler);
urlStream.removeEventListener(Event.COMPLETE, urlStream_completeHandler);
urlStream.removeEventListener(IOErrorEvent.IO_ERROR, urlStream_ioErrorHandler);
urlStream.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, urlStream_securityErrorHandler);

//fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, fileStream_outputProgressHandler)
//fileStream.removeEventListener(IOErrorEvent.IO_ERROR, fileStream_ioErrorHandler);

urlStream = null;
//fileStream = null;
}

private function writeToDisk():void {
/*var fileData:ByteArray = new ByteArray();
urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
fileStream.writeBytes(fileData,0,fileData.length);
waitingForDataToWrite = false;*/

var bytes:ByteArray = new ByteArray();
urlStream.readBytes( bytes );

var fs:FileStream = new FileStream();
fs.open( file, FileMode.APPEND );
fs.writeBytes( bytes );
fs.close();
}




}
}

最佳答案

正如我在对 csomakk 的评论中所说,我已经使用 URLStream 分块方法通过 AIR 为桌面、iOS 和 Android 成功下载了 300+ MB 文件。

伪代码:

var stream:URLStream = new URLStream();
stream.addEventListener( PROGRESS, progressHandler );
stream.addEventListener( COMPLETE, completeHandler );
stream.load( url );

private function progressHandler( e:ProgressEvent ):void {
this.writeDataToDisk();
}

private function completeHandler( e:Event ):void {
this.writeDataToDisk();
}

private function writeDataToDisk():void {
var bytes:ByteArray = new ByteArray();
this.stream.readBytes( bytes );

var fs:FileStream = new FileStream();
fs.open( file, FileMode.APPEND );
fs.writeBytes( bytes );
fs.close();
}

该基本逻辑在 300MB 以内运行良好(并且可能更远。虽然我应该测试一下,但现在我想起来了)。写得相当快,所以可能会有一些错误,而且我确实遗漏了一些东西,但你明白了。

如果这不起作用,我们需要您提供一些信息:

  1. 发布任何错误
  2. fs.close() 之后追踪 file.size/1024/1024 + "MB" 并查看它在崩溃前走了多远
  3. 在 fs.close()` 之后跟踪 System.memory/1024/1024 + "MB"以便我们可以监控内存使用情况



对于 2 和 3,我们应该只需要崩溃发生前的最后跟踪语句。



或者,您应该知道您无法在应用程序中对这个 500MB 的文件执行任何操作。由于它的大小,Flash 根本不会加载它。我设法摆脱 300MB 视频文件的唯一原因是我们是从磁盘流式传输它们,而不是将整个内容存储到内存中。








关于actionscript-3 - AIR (As3) - 通过 iPad 应用程序下载大文件,我们在Stack Overflow上找到一个类似的问题:

https://stackoverflow.com/questions/14583247/




25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com