2008.08.25 21:23

플래시 플레이어 10에서 로컬 파일 핸들링 하기


플래시 플레이어 10 의 신기능 중 하나인 FileReference API를 사용하면 플래시가 서버를 거치지 않고
직접 로컬 파일을 불러오고 저장할 수 있다.

플래시 플레이어 10이 나오기 전에는 로컬 시스템에 파일을 읽거나 저장하려면 반드시 중계서버를 거쳐야만 했다.
사실 이러한 방법은 별로 좋지 않을 뿐만 아니라 불필요한 리소스를 사용하고 지연을 야기시켰다.

이 새로운 기능은 다음 두가지 함수를 통해서 사용할 수 있다.

FileReference.load() : 사용자가 선택한 파일을 불러오는 기능
FileReference.save() : 사용자가 선택한 위치에 파일을 저장하는 기능

단, 유의해야 할 몇가지 사항이 있다.

  • load()와 save() API는 반드시 버튼 클릭과 같은 사용자의 이벤트에 의해서만 실행된다.
  • 파일을 저장하거나 불러오는 주소는 액션스크립트 상에서 노출되지 않는다.
  • 이 API는 비동기적으로 작동한다.
아래 두가지 예제는 이 API를 어떻게 사용하는지 알려준다.
예제들은 Flex에서 작성된 것이지만 주석이 친절하게 달려있기 때문에 순수 액션스크립트만 참고하는데
문제가 없을 것이다.

파일 불러오기 :
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>
<![CDATA[
import flash.net.FileReference;
import flash.net.FileFilter;

import flash.events.IOErrorEvent;
import flash.events.Event;

import flash.utils.ByteArray;

//FileReference Class well will use to load data
private var fr:FileReference;

//File types which we want the user to open
private static const FILE_TYPES:Array = [new FileFilter("Text File", "*.txt;*.text")];

//called when the user clicks the load file button
private function onLoadFileClick():void
{
//create the FileReference instance
fr = new FileReference();

//listen for when they select a file
fr.addEventListener(Event.SELECT, onFileSelect);

//listen for when then cancel out of the browse dialog
fr.addEventListener(Event.CANCEL,onCancel);

//open a native browse dialog that filters for text files
fr.browse(FILE_TYPES);
}

/************ Browse Event Handlers **************/

//called when the user selects a file from the browse dialog
private function onFileSelect(e:Event):void
{
//listen for when the file has loaded
fr.addEventListener(Event.COMPLETE, onLoadComplete);

//listen for any errors reading the file
fr.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);

//load the content of the file
fr.load();
}

//called when the user cancels out of the browser dialog
private function onCancel(e:Event):void
{
trace("File Browse Canceled");
fr = null;
}

/************ Select Event Handlers **************/

//called when the file has completed loading
private function onLoadComplete(e:Event):void
{
//get the data from the file as a ByteArray
var data:ByteArray = fr.data;

//read the bytes of the file as a string and put it in the
//textarea
outputField.text = data.readUTFBytes(data.bytesAvailable);

//clean up the FileReference instance

fr = null;
}

//called if an error occurs while loading the file contents
private function onLoadError(e:IOErrorEvent):void
{
trace("Error loading file : " + e.text);
}

]]>
</mx:Script>

<mx:Button label="Load Text File" right="10" bottom="10" click="onLoadFileClick()"/>
<mx:TextArea right="10" left="10" top="10" bottom="40" id="outputField"/>

</mx:Application>

파일 저장하기 :

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">

<mx:Script>
<![CDATA[

import flash.net.FileReference;

import flash.events.IOErrorEvent;
import flash.events.Event;

private static const DEFAULT_FILE_NAME:String = "example.txt";

//FileReference Class well will use to save data
private var fr:FileReference;

/********** UI Event Handlers **************/

//called when the users types in the textarea
//note valueCommit should be used, but is broken in the flex build
//I am using
private function onInputChange():void
{
//enable button if there is any text to save
saveButton.enabled = (inputField.text.length > 0);
}

//called when the user clicks the load file button
private function onSaveClick():void
{
//create the FileReference instance
fr = new FileReference();

//listen for the file has been saved
fr.addEventListener(Event.COMPLETE, onFileSave);

//listen for when then cancel out of the save dialog
fr.addEventListener(Event.CANCEL,onCancel);

//listen for any errors that occur while writing the file
fr.addEventListener(IOErrorEvent.IO_ERROR, onSaveError);

//open a native save file dialog, using the default file name
fr.save(inputField.text, DEFAULT_FILE_NAME);
}

/***** File Save Event Handlers ******/

//called once the file has been saved
private function onFileSave(e:Event):void
{
trace("File Saved");
fr = null;
}

//called if the user cancels out of the file save dialog
private function onCancel(e:Event):void
{
trace("File save select canceled.");
fr = null;
}

//called if an error occurs while saving the file
private function onSaveError(e:IOErrorEvent):void
{
trace("Error Saving File : " + e.text);
fr = null;
}
]]>
</mx:Script>

<mx:Button label="Save File" right="10" bottom="10" id="saveButton"
click="onSaveClick()" enabled="false"/>
<mx:TextArea right="10" left="10" top="36" bottom="40" id="inputField"
editable="true" change="onInputChange()"/>
<mx:Label text="Enter text to save" left="10" top="10" fontWeight="bold"/>

</mx:Application>


추가적으로 위의 예제에서 사용된 두가지 이벤트는 API에 의해서 발생한 것이다.

ProgressEvent.PROGRESS : 파일을 읽거나 쓸 때의 진행상태를 보여준다.

Event.OPEN : 파일이 열렸을 경우 발생한다.

이 API는 Adobe AIR에서도 사용가능 하게 될 것이지만 사실 AIR의 파일 API가 저 유연하고 강력한 기능을 제공한다.

원문 : 마이크 챔버스 블로그

Trackback 0 Comment 1
  1. dlvm 2010.05.06 20:31 address edit & del reply

    잘봤어요 감사합니다 ^,^