AS3: URLStream saving files to desktop?
i found a few scripts online and combined them to this. I want to download files from the web to my local harddrive. Any idea what i'm doing wrong?
var fs:FileStream;
var stream:URLStream;
var _output:Boolean = false;
init();
startDownload('http://www.teachenglishinasia.net/files/u2/purple_lotus_flower.jpg');
function init() {
stream = new URLStream();
stream.addEventListener(ProgressEvent.PROGRESS, _dlProgressHandler);
stream.addEventListener(Event.COMPLETE, _dlCompleteHandler);
stream.addEventListener(Event.OPEN, _dlStartHandler);
fs = new FileStream();
fs.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, _writeProgressHandler)
}
function startDownload(url:String):void {
//fs.openAsync(lfile, FileMode.APPEND);
_output = false;
stream.load(new UR开发者_Go百科LRequest(url));
}
function downloadComplete():void {
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,0,stream.bytesAvailable);
fs.writeBytes(fileData,0,fileData.length);
fs.close();
}
function writeToDisk():void {
_output = false;
var fileData:ByteArray = new ByteArray();
stream.readBytes(fileData,0,stream.bytesAvailable);
fs.writeBytes(fileData,0,fileData.length);
}
function _dlProgressHandler(evt:ProgressEvent):void {
if(_output){
writeToDisk();
}
}
function _dlCompleteHandler(evt:Event):void {
downloadComplete();
}
function _dlStartHandler(evt:Event):void {
_output = true;
}
function _writeProgressHandler(evt:OutputProgressEvent):void{
_output = true;
}
Flash keeps telling me: Error: Error #2029: This URLStream object does not have a stream opened. However the connection to the webpage goes out.
Any ideas? Thank you for your help!
I modified your code and here is a working Downloader class. (@SébastienNussbaumer improved this answer and @TobiasKienzler reviewed changes: thanks a lot guys!)
Simple to use:
var downLoader:Downloader = new Downloader();
downLoader.addEventListener(DownloadEvent.DOWNLOAD_COMPLETE, function(event:DownloadEvent):void{
trace("Download complete: ");
trace("\t"+event.url);
trace("->\t"+event.file.url);
});
var file:File = File.applicationStorageDirectory.resolvePath("downloaded.mp3");
downLoader.download("http://dl.dropbox.com/u/18041784/Music/Lana%20Del%20Rey%20-%20Born%20To%20die%20%28Gemini%20Remix%29.mp3", file);
Output when download complete:
Download complete:
http://dl.dropbox.com/u/18041784/Music/Lana%20Del%20Rey%20-%20Born%20To%20die%20%28Gemini%20Remix%29.mp3
-> app-storage:/downloaded.mp3
Enjoy:-)
package com.tatstyappz.net
{
import flash.events.DataEvent;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.OutputProgressEvent;
import flash.events.ProgressEvent;
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 Downloader extends EventDispatcher
{
[Event(name="DownloadComplete", type="com.tatstyappz.net.DownloadEvent")]
private var file:File;
private var fileStream:FileStream;
private var url:String;
private var urlStream:URLStream;
private var waitingForDataToWrite:Boolean = false;
public function Downloader()
{
urlStream = new URLStream();
urlStream.addEventListener(Event.OPEN, onOpenEvent);
urlStream.addEventListener(ProgressEvent.PROGRESS, onProgressEvent);
urlStream.addEventListener(Event.COMPLETE, onCompleteEvent);
fileStream = new FileStream();
fileStream.addEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeProgressHandler)
}
public function download(formUrl:String, toFile:File):void {
this.url = formUrl;
this.file = toFile;
fileStream.openAsync(file, FileMode.WRITE);
urlStream.load(new URLRequest(url));
}
private function onOpenEvent(event:Event):void {
waitingForDataToWrite = true;
dispatchEvent(event.clone());
}
private function onProgressEvent(event:ProgressEvent):void {
if(waitingForDataToWrite){
writeToDisk();
dispatchEvent(event.clone());
}
}
private function writeToDisk():void {
var fileData:ByteArray = new ByteArray();
urlStream.readBytes(fileData, 0, urlStream.bytesAvailable);
fileStream.writeBytes(fileData,0,fileData.length);
waitingForDataToWrite = false;
dispatchEvent(new DataEvent(DataEvent.DATA));
}
private function writeProgressHandler(evt:OutputProgressEvent):void{
waitingForDataToWrite = true;
}
private function onCompleteEvent(event:Event):void {
if(urlStream.bytesAvailable>0)
writeToDisk();
fileStream.close();
fileStream.removeEventListener(OutputProgressEvent.OUTPUT_PROGRESS, writeProgressHandler);
dispatchEvent(event.clone());
// dispatch additional DownloadEvent
dispatchEvent(new DownloadEvent(DownloadEvent.DOWNLOAD_COMPLETE, url, file));
}
}
}
And the event class:
package com.tatstyappz.net
{
import flash.events.Event;
import flash.filesystem.File;
public class DownloadEvent extends Event
{
public static const DOWNLOAD_COMPLETE:String = "DownloadComplete";
public var url:String;
public var file:File;
public function DownloadEvent(type:String, url:String, file:File)
{
super(type, true);
this.url = url;
this.file = file;
}
override public function toString():String{
return super.toString() + ": "+ url + " -> "+file.url;
}
}
}
This is a long shot, since I've never worked with FileStream
(and since the error message you pasted says 'this URLStream object etc'). But, It seems you FileStream
object (fs
) is not open and you are trying to 1) write to it and then 2) close it. My understanding is that any of those operations should throw an error if the file is not open. So, maybe it's worth cheking that. Other than that, can you paste a stack trace of the error, so it's more clear where it originates? (Tip: if you are compiling with the Flash IDE, check permit debugging in the actionscript settings; this will give you more verbose error messages and line numbers; this is of great help when debugging / troubleshooting).
精彩评论