WonHada.com으로 이전

파일 시스템 API 사용[한글 번역] 본문

Adobe AIR

파일 시스템 API 사용[한글 번역]

반주부 2007. 11. 14. 20:06
반응형

** 이 자료는 AIR 알파버젼 문서의 내용입니다..현재는 베타2가 나와 있으니 새로운 문서도 꼭 참고 하시기 바랍니다..기본 개념은 같고 메소드 이름이 바뀐게 보이네요..

<파일 시스템 API 사용>

아폴로는 사용자 컴퓨터의 파일과 디렉토리의 읽기, 쓰기를 허용하는 파일 I/O API를 제공합니다. 파일 I/O API는 다음과 같은 기능을 포함합니다:

- 파일과 디렉토리의 생성, 삭제
- 파일과 디렉토리의 복사, 이동
- 디렉토리 있는 컨텐츠의 리스트 표시
- 파일과 디렉토리의 시스템 정보 얻기
- 바이너리 파일 읽기/쓰기
- 텍스트 파일 읽기/쓰기
- 액션스크립트 오브젝트의 직렬화 및 역직렬화
*(직렬화 - 인스턴스화 한 클래스 객체를 파일로 저장)

파일 시스템 작업을 위한 로우-레벨 기능은 액션스크립트를 통해 접근됩니다. 아폴로를 위한 플렉스 프레임웍은 파일과 디렉토리 작업을 위한 컴포넌트가 포함됩니다. 그러나 이것은 파일 시스템 운행과 파일과 디렉토리를 선택하기 위한 그래픽 컴포넌트입니다. 그것들은 근본적인 파일 I/O 조작은 직접적으로 허용하지는 않습니다.

이 장의 정보에 더하여, 5장 "파일 시스템을 통한 작업"을 보십시오. 이 장에서 설명한 개념에 대한 실제 예제들을 보여주고, 플렉스 빌더 또는 아폴로 SDK를 사용해서 여러분이 테스트할 수 있는 MXML 코드를 제공합니다.

<보안 모델>

아폴로는 최종적으로 파일시스템 같은 로컬 자원의 접근을 위한 완벽한 보안 모델을 제공할 것입니다. 그러나, 아직 이 보안 모델은 아폴로 알파에는 갖춰지지 않았습니다.

아폴로 어플리케이션이 사용자의 컴퓨터로부터 설치되고 실행된다는 것은 중요합니다. 아폴로 어플리케이션은 웹브라우저와는 다른 보안 컨텍스트와 보안 모델을 가집니다. 이 때문에, 다른 어플리케이션을 전송 및 실행에 적용하는 동일한 규칙은 아폴로 어플리케이션의 전송 및 실행에 적용합니다. 사용자는 믿을수 있는 소스만 다운로드하고 설치하게 됩니다.

<파일과 디렉토리 접근>

아폴로 어플리케이션은 윈도우와 맥OS를 포함해서 다양한 플랫폼에서 실행될 수 있습니다. 아폴로 파일 API는 'platform-neutral code syntax' 를 사용합니다.

예를들어, 여러분이 맥OS와 윈도우 사이의 다른 파일 경로를 나타내려 한다면..

- 맥OS의 전형적인 파일 경로는 '/Users/joe/Documents/test.txt' 입니다.
- 윈도우의 전형적인 파일 경로는 'C:\Documents and Settings\joe\My Documents\test.txt' 입니다.

하지만, 여러분은 아폴로 컴포넌트, 클래스, 메소드 그리고 속성등을 이용해 파일 접근을 동일하게 할 수 있습니다.

액션스크립트 파일 오브젝트는 파일 또는 디렉토리의 포인터입니다. 'File' 클래스는 'documentsDirectory' 라는 정적 속성을 가지는데 사용자 디렉토리의 포인터인 파일 오브젝트를 포함합니다. 이것은 윈도우의 'My Documents directory', 맥OS 사용자 디렉토리의 'Documents subdirectory' 입니다. 다음 코드를 확인하세요.

trace(File.documentsDirectory.nativePath)
// On Windows:
// C:\Documents and Settings\joe\MyDocuments
// On Mac OS: /Users/joe/Documents

여러분은 resolve() 메소드를 이용해서 디렉토리 내의 파일 또는 서브디렉토리를 수정할 수 있습니다. 예를들어, 다음에 나오는 코드는 사용자 디렉토리에 'Apollo Test' 서브디렉토리를 생성합니다.

var newDir:File = File.documentsDirectory;
newDir = newDir.resolve("ApolloTest");
newDir.createDirectory( );

파일 오브젝트는 파일 또는 디렉토리 어느 한쪽을 가리킬 수 있습니다. 또한, 이전 예제에서 살펴본대로 파일 오브젝트는 존재하지 않는 파일 및 디렉토리를 가리킬 수도 있습니다.

<디렉토리 접근을 위한 File 클래스 속성>

File 클래스는 일반적으로 디렉토리를 사용하기 위한 다음과 같은 정적 속성을 포함합니다.

File.appStorageDirectory
- 각 설치된 아폴로 어플리케이션은 유일한 'application storage directory'가 주어집니다. 이것은 로그 파일, 캐시 파일 및 참조 파일이 포함될 수 있습니다.

File.appResourceDirectory
- 어플리케이션의 설치 디렉토리

File.currentDirectory
- 런칭된 파일디렉토리입니다.

File.desktopDirectory
- 유저의 데스크탑 디렉토리입니다.

File.documentsDirectory
- 윈도우의 'My Documents' 입니다.(맥OS 'Documents subdirectory')

File.userDirectory
- 사용자의 홈 디렉토리입니다. 예를 들면, 맥OS에서는 'Users/username'이며 윈도우에서는 'c:\\Document and Settings\username'입니다.


<파일 오브젝트(File Object)의 url, nativePath 속성>

파일 오브젝트의 'url' 속성은 파일 또는 폴더의 위치를 string으로 반환합니다.

var directory:File = File.userDirectory;
trace(directory.url)
// on Windows: file:///C:/Documents%20and%20Settings
// on Mac OS: file:///Users

그에 반해 'nativePath' 속성은 윈도우 또는 맥OS의 유일한 string을 반환합니다. 예를 들면, 여러분은 이 코드를 이용해 윈도우 컴퓨터의 파일을 가리킬 수 있습니다.

var file:File = new File( );
file.nativePath = "c:/ApolloTest/surprise.txt";

그러나, 디렉토리를 알기위해서는 이전 섹션의 'File.appStorageDirectory'와 같은 표에 있던 하나로 시작하는게 좋습니다. 다음 코드와 같이 디렉토리의 상대경로를 생성하는 resolve() 메소드를 사용합니다.

var logFile:File = File.appStorageDirectory;
logFile = logFile.resolve("log.txt");

앞으로 여러분의 어플리케이션을 접근할 수 있도록 저장된 디렉토리를 사용합니다.

<URI Schemes>

URI 스키마는 다음 예의 파일과 같은 URL의 처음에 지정됩니다.

file:///c:/ApolloTest/test.txt

게다가 파일 URI 스키마에 대해서 아폴로는 새로운 URI 스키마(app-storage, app-resource)를 제공합니다.

app-storage
- 어플리케이션 저장 디렉토리를 확인합니다.

var logFile:File = File.appStorageDirectory;
logFile = logFile.resolve("log.txt");
trace(logFile.url); // app-storage:/log.txt

app-resource
- 어플리케이션의 설치 폴더를 확인합니다.

var installDir:File = new File( );
installDir.url = "app-resource:/";
installDir = installDir.resolve("HelloWorld-app.xml");
trace(installDir.url); // app-resource:/HelloWorld-app.xml

file
- 파일 오브젝트의 url 속성은 기본적인 파일 URL 스키마를 반환합니다.

var file:File = File.documentsDirectory;
file = file.resolve("ApolloTest/test.txt");
trace(file.url);
// On Windows:
// file:///C:/Documents%20and %20Settings/ ... /test.txt
// On Mac OS:
// file:///Users/userName/Documents/ ... /test.txt

<메소드의 비동기 및 동기 버젼>

File 클래스의 몇가지 메소드(File.copyFile(), File.copyFileAsync()와 같은)와 FileStream 클래스는 동기 및 비동기 버젼을 둘 다 가집니다.

동기 메소드는 파일 조작이 완료될때까지 단념하지 않습니다. 비동기 메소드는 같은 시간에 다른 액션스크립트 프로세스를 허용하는 백그라운드에서 실행되며, 비동기 파일 조작이 끝났을 때, 끝난것을 리스너에서 이벤트로 알립니다.

여기 파일을 복사하는 동기 메소드 copyTo()의 예제가 있습니다.

var file1:File = File.documentsDirectory.
resolve("ApolloTest/test.txt");
var file2:File = File.documentsDirectory.
resolve("ApolloTest/copy of test.txt");
file1.copyTo(file2);
trace("Not output until the file is copied.");

아래는 비동기로 파일을 복사하는 copyToAsync()의 예제입니다.

var file1:File = File.documentsDirectory.
resolve("ApolloTest/test.txt");
var file2:File = File.documentsDirectory.
resolve("ApolloTest/copy of test.txt");
file1.copyToAsync(file2);
file1.addEventListener(Event.COMPLETE, completeHandler);
trace("This line executes before the complete event.");
trace("So does this line.");
private function completeHandler(event:Event):void {
trace("Done.");
}

다음 표는 File 클래스의 비동기 메소드와 이벤트입니다.

copyToAsync()              complete, ioError
deleteDirectoryAsync()     complete, ioError
deleteFileAsync()          complete, ioError
listDirectoryAsync()       directoryListing, ioError
moveToAsync()              complete, ioError
moveToTrashAsync()         complete, ioError

파일을 열때는 FileStream 오브젝트의 open() 또는 openAsync() 메소드중 하나를 사용합니다. 전자는 동기로 파일을 열고, 후자는 비동기로 파일을 엽니다. 더 자세한 내용은 다음 장의 "The open() and openAsync() Methods"를 보세요.

프로그레스 바와 같은 것은 비동기 메소드를 사용하세요. 예를 들어 용량이 적은 파일(1MB 또는 그 이하의)을 쓰려 한다면 open() 메소드를 사용할 수 있고 큰 파일 또는 파일 크기를 모를때는 openAsync() 메소드를 사용할 수 있습니다.

비동기 메소드에 대해 더 자세히 알고 싶다면, 아래 주소에 있는 'Programming ActionScript 3.0'의 "Handling Events" 장을 보십시오.

http://livedocs.macromedia.com/flex/2/docs/Part5_ProgAS.html

<디렉토리 컨텐츠 읽기>

File.listDirectory() 메소드는 파일과 디렉토리 리스트를 배열(Array)로 반환합니다. 다음 코드는 데스크탑 디렉토리의 컨텐츠 리스트를 보여줍니다.

var directory:File = File.desktopDirectory;
var contents:Array = directory.listDirectory();
for (var i:uint = 0; i < contents.length; i++) {
 if (contents[i].isDirectory) {
  trace(contents[i].name);
 } else {
  trace(contents[i].name,
  contents[i].size,
  "bytes");
 }
}

File.listDirectory() 메소드는 단지 루트 레벨의 파일만 반환합니다. 서브디렉토리는 검사하지 않습니다. 하지만 여러분은 File.listDirectoryAsync()를 사용해서 서브디렉토리를 통하는 코드를 작성할 수 있습니다.

5장의 "Getting a Directory Listing"을 참조하세요.

<파일 정보 얻기>

File 클래스는 파일과 디렉토리에 대한 정보를 알아내는 속성이 몇가지 있습니다.

exists
- 파일 또는 디렉토리가 존재하는지 알아냅니다.

isDirectory
- 파일 오브젝트 포인트가 디렉토리인지(true) 아닌지(false)를 반환합니다.

isHidden
- 숨김 파일 또는 디렉토리인지 알아냅니다.

nativePath
- 파일 또는 디렉토리의 경로를 나타냅니다.

parent
- 부모 디렉토리를 나타냅니다.

url
- 파일 또는 디렉토리의 경로를 나타냅니다.

File 클래스는 또한 FileReference 클래스로부터 다음의 유용한 속성들을 상속 받습니다.

creationDate
- 파일 또는 폴더가 생성된 날짜를 나타냅니다.

modificationDate
- 마지막 수정된 날짜를 나타냅니다.

name
- 파일 또는 폴더의 이름을 나타냅니다.

size
- 파일의 사이즈를 나타냅니다. (bytes)

<파일, 디렉토리의 복사 및 이동>

File.copyTo(), File.moveTo() 메소드는 파일 또는 디렉토리를 복사, 이동합니다. 다음 예는 사용자 디렉토리(Apollo Test)의 'test.txt' 파일을 어플리케이션 스토리지 디렉토리(User Data)로 복사합니다.

var file1:File = File.documentsDirectory.resolve("Apollo
Test/test.txt");
var destination:File = File.appStorageDirectory.
resolve("User Data");
destination.createDirectory( );
var file2:File = destination.resolve("test.txt");
file1.copyTo(file2);

주) 디렉토리가 존재하는지 확인하려고 File.createDirectory() 메소드 호출

다음 코드는 'Apollo Test 1' 디렉토리를 'Apollo Test 2' 디렉토리로 이동하는데 사실상 이것은 디렉토리 이름을 바꾼 것입니다.

var dir1:File = File.documentsDirectory;
dir1 = dir1.resolve("Apollo Test 1");
var dir2:File = File.documentsDirectory;
dir2 = dir2.resolve("Apollo Test 2");

복사 또는 이동이 오래 걸릴것 같다면, 위 메소드들의 비동기 버젼을 사용해도 됩니다. File.copyToAsync()와 File.moveToAsync()가 그것입니다.

각 메소드들은 'clobber'라는 파라미터가 있는데 파일을 덮어씌울때 true로 설정해서 사용할 수 있습니다. 기본값은 false 입니다.

<파일과 디렉토리의 생성>

File 클래스의 File.createTempFile()과 File.createTempDirectory() 정적 메소드는 임시 파일 또는 디렉토리를 생성하게 합니다. 아폴로는 이 메소드들에 의해 생성된 새롭고 유일한 임시 파일 또는 디렉토리를 확보합니다. 다음 코드는 임시 파일을 생성합니다.

var bufferStorage:File = File.createTempFile( );

임시 파일, 디렉토리는 아폴로 어플리케이션이 닫힐때 자동으로 삭제되지 않습니다. 어플리케이션이 닫힐때 삭제하고 싶다면 다음 섹션, "Deleting Files and Directories"를 보십시오.

File.createDirectory() 메소드는 파일 오브젝트에 의해 기술된 경로의 디렉토리에 생성합니다.

var directory = File.documentsDirectory;
directory = directory.resolve("ApolloTest");

필요에 의해 FileStream 오브젝트가 열릴때 디렉토리가 자동으로 생성되어 쓰여집니다. FileStream 오브젝트에 대해 더 자세한 내용이 필요하다면 이 장 마지막의 "Reading and Writing Files" 를 보십시오.

<파일과 디렉토리의 삭제>

File.deleteFile() 메소드는 파일을 영구 삭제하고 File.deleteDirectory() 메소드는 디렉토리를 영구 삭제합니다. File.moveToTrash() 메소드는 파일 또는 디렉토리(시스템 trash(쓰레기))를 이동합니다.

각 메소드는 비동기의 한 측면을 가집니다.

<파일 읽고 쓰기>

FileStream 클래스는 어플리케이션이 파일을 읽고 쓰도록 해줍니다.

파일을 읽고 쓰는 기본 프로세스가 다음에 있습니다.

1. 읽기, 쓰기를 원하는 파일의 지점을 셋업합니다.
자세한 내용은 이 장 초반부의 "Accessing Files and Directories"를 참고하세요.

2. FileStream 오브젝트의 예시

var stream:FileStream = new FileStream( );

3. file 파라미터와 같은 File 오브젝트와 fileMode 파라미터와 같은 적절한 파일 모드를 가지고  FileStream.open() 또는 FileStream.openAsync() 메소드를 호출

stream.open(file, FileMode.READ);

자세한 내용은 이 장 후반부의 "File Open Modes"를 참고하세요.

4. 만약 FileStream.openAsync() 메소드를 호출했다면 적절한 이벤트 리스너를 생성하십시오.
자세한 내용은 다음의 "The open() and openAsync() Methods"를 참고하세요.

5. 데이터 읽기, 쓰기 메소드를 호출하십시오.
자세한 내용은 이 장 후반부의 "Read and Write Methods"를 참고하세요.

6. FileStream.close() 메소드를 이용해 파일을 닫습니다.

코드예)
 stream.close( );

3, 4, 5 단계는 다음 섹션에 더 자세히 보실 수 있습니다. 우선, UTF-8 텍스트 파일을 동기적으로 읽는 샘플 코드를 보시죠.

var file:File = File.appStorageDirectory;
file = file.resolve("settings.xml");
var stream:FileStream = new FileStream( );
stream.open(file, FileMode.READ);
var data:String = stream.readUTFBytes(stream.
bytesAvailable);
stream.close( );

다음은 비동기로 같은 데이터를 읽습니다.

var file:File = File.appStorageDirectory;
file = file.resolve("settings.xml");
var stream:FileStream = new FileStream( );
stream.openAsync(file, FileMode.READ);
stream.addEventListener(Event.COMPLETE, readData);
var data:String;
private function readData(event:Event):void {
data = stream.readUTFBytes(stream.bytesAvailable);
stream.close( );
}

<open()과 openAsync() 메소드>

여러분의 어플리케이션은 파일의 읽고 쓰기전에 파일을 열 필요가 있습니다.

FileStream.openAsync() 메소드로 파일을 열때, 파일은 비동기로 열리고 여러분은 이벤트 리스너를 동록합니다.

FileStream.open() 메소드는 파일을 동기로 엽니다. 만약 여러분이 만든 어플리케이션이 이 동기 메소드로 파일을 연다면, 동기가 잘 완료되고 read 또는 write 메소드를 호출합니다.

다음은, 다음 호출이 생성되기 이전에 stream.open(), stream.writeUTFBytes(), and stream.close() 메소드가 완료되는 예제를 보여줍니다.

var newFile:File = File.documentsDirectory;
file = file.resolve("ApolloTest/test.txt");
var stream:FileStream = new FileStream( )
stream.open(file, FileMode.WRITE);
stream.writeUTFBytes("This is some sample text.");
stream.close( );

파일을 여는 동기 작업의 장점은 코드를 적게 쓴다는 것입니다. 단점은 다른 액션스크립트 코드의 실행이 지연될 수 있다는 것입니다. 결과적으로, 큰 파일을 가지고 작업하거나 느린 네트워크를 통해 파일을 연다면 FileStream.openAsync() 메소드를 고려해야 합니다.

다음 프로세스는 openAsync() 메소드를 사용하는 비동기에 대한 것입니다.

Closing the file
- FileStream 오브젝트는 파일이 닫힐때 close 이벤트를 발생합니다.

Reading data into the read buffer
- FileStream 오브젝트는 데이터를 읽을때 progress 이벤트를 발생하고, 모두 읽으면 complete 이벤트를 발생합니다. 단지 데이터를 읽는거라면 readBytes()와 같은 동기 메소드를 호출합니다.

I/O errors
- FileStream 오브젝트는 에러를 만나면 ioError 이벤트를 발생시킵니다. 이것은 몇가지 이유로 발생하는데, 파일이 없거나 읽기전용(쓰기방지)일 경우와 같은 것들입니다. 몇몇 에러들은 예외를 던지거나, 파일이 열려있지 않았을때도 발생합니다.

FileStream.openAsync() 메소드를 호출하기 전에 어플리케이션은 이벤트를 받을 이벤트 리스너 함수를 등록합니다. 다음 예는 비동기로 파일을 읽습니다. 파일이 열린 후, complete 이벤트가 발생합니다.(만약 에러가 발생한다면, ioError 이벤트가 발생합니다)
completeHandler() 메소드가 FileStream을 호출합니다. readBytes() 메소드는 비동기로 바이트의 배열과 같은 파일로 부터 데이터를 받습니다. 파일을 다 받으면 complete 이벤트가 발생합니다.

var file:File = File.documentsDirectory.
resolve("ApolloTest/test.txt");
var stream:FileStream = new FileStream( );
stream.addEventListener(ProgressEvent.PROGRESS,
progressHandler);
stream.addEventListener(Event.COMPLETE, completeHandler);
stream.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
stream.addEventListener(Event.CLOSE, closeHandler);
stream.openAsync(file, FileMode.READ);
var data:ByteArray = new ByteArray( );
private function progressHandler(event:ProgressEvent):void {
 trace(stream.bytesAvailable, "bytes read.");
}
private function completeHandler(event: Event):void {
 data = stream.readBytes(stream.bytesAvailable);
 stream.close( );
}
private function ioErrorHandler(event:IOErrorEvent):void {
 trace("An I/O error was encountered.");
}
private function closeHandler(event: Event):void {
 trace("File closed.");
}

<파일 열기 모드>

FileStream.open()과 FileStream.openAsync() 메소드는 둘 다 두개의 파라미터를 가집니다. file 파라미터는 열기 원하는 파일을, fileMode 파라미터는 FileStream 오브젝트의 string 정의입니다. fileMode 파라미터는 FileMode 클래스에서 상수로 정의합니다.

다음 코드는 동기로 파일을 엽니다. 하지만 읽지는 않습니다.

stream.open(file, FileMode.WRITE);

여기 FileMode 상수를 정리했습니다.

FileMode.APPEND
- 쓰기전용 모드로 파일을 엽니다. 파일을 열때 파일이 없다면 생성합니다.

FileMode.READ
- 읽기전용 모드로 파일을 엽니다. 파일이 반드시 있어야 합니다.(없어도 생성하지 않습니다)

FileMode.UPDATE
- 읽기/쓰기 모드로 파일을 엽니다. 파일을 수정할 수 있습니다. 파일을 열때 파일이 없다면 생성합니다.

FileMode.WRITE
- 쓰기전용 모드로 파일을 엽니다. 파일이 없다면 생성합니다. 파일이 있다면 덮어쓰기 합니다.

<읽기와 쓰기 메소드>

FileStream 클래스는 읽기, 쓰기 메소드를 몇개 가지고 있습니다. 예를 들면, 바이트의 배열을 읽고 쓰기위해 readUTFBytes()와 writeUTFBytes() 메소드를 사용할 수 있습니다. 그에 반해 readByte()와 writeByte() 메소드는 싱글 바이트를 읽고 씁니다. 모두, 26개의 읽기, 쓰기 메소드가 있습니다. 자세한 내용은 "ActionScript 3.0 Language Reference"의 이 메소드들에 대해 읽어 보십시오.

readUTFBytes()와 writeUTFBytes() 메소드는 UTF-8로 인코딩 된 텍스트를 읽고 씁니다. readMultiByte()와 writeMultiByte() 메소드는 여러가지로 인코딩된 피일에 쓰입니다. 다음 예에서, UTF 파일은 UTF로 인코딩 된 UTF byte order mark (BOM) 문자를 가지고 시작합니다.

자세한 내용을 원한다면, Apollo Developer's Guide (http://www.adobe.com/go/apollodocs)의 "Data formats, and choosing the read and write methods to use"를 참고하십시오.

반응형