- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
首先我要说明的是,我不能发布源代码,因为项目很大。我正在尝试在 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 以内运行良好(并且可能更远。虽然我应该测试一下,但现在我想起来了)。写得相当快,所以可能会有一些错误,而且我确实遗漏了一些东西,但你明白了。
如果这不起作用,我们需要您提供一些信息:
fs.close()
之后追踪 file.size/1024/1024 + "MB"
并查看它在崩溃前走了多远System.memory/1024/1024 + "MB"以便我们可以监控内存使用情况
对于 2 和 3,我们应该只需要崩溃发生前的最后跟踪语句。
或者,您应该知道您无法在应用程序中对这个 500MB 的文件执行任何操作。由于它的大小,Flash 根本不会加载它。我设法摆脱 300MB 视频文件的唯一原因是我们是从磁盘流式传输它们,而不是将整个内容存储到内存中。
关于actionscript-3 - AIR (As3) - 通过 iPad 应用程序下载大文件,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/14583247/
我是一名优秀的程序员,十分优秀!