수요일 FAQ 시간이 돌아왔습니다. 오늘은 서브 폴더와 파일들에 접근하는 것에 대한 FAQ 입니다.
1. How do you create a new sub-folder within the Documents or Temporary directory?
루아 파일 시스템(LFS)을 통해서 디렉토리에 서브 폴더를 추가할 수 있습니다. Resource 디렉토리는 modify 될 수 없는 read-only 입니다.
아래에 Documents 디렉토리에 어떻게 Images 폴더를 생성할 수 있는지에 대한 예제가 있습니다.
local lfs = require "lfs" -- get raw path to app's Documents directory local docs_path = system.pathForFile( "", system.DocumentsDirectory ) -- change current working directory local success = lfs.chdir( docs_path ) -- returns true on success local new_folder_path local dname = "Images" if success then lfs.mkdir( dname ) new_folder_path = lfs.currentdir() .. "/" .. dname end
여기에서 LFS 에 대한 좀 더 자세한 정보를 얻으실 수 있습니다.
2. How do you access (read or write) a file that has been placed in a sub-folder?
여러분은 두가지 방법으로 서브 폴더에 있는 파일에 access 하실 수 있습니다. 그 파일로 무엇을 할 것인지에 따라 접근하는 방법이 다른데요. 이미지를 display 하거나 sound 를 play 하신다면 서브 폴더 이름에 파일이름을 연결해서 거기에 base 디렉토리를 지정해 주시면 됩니다. 예를 들어 Document 디렉토리의 Images 서브폴더에 있는 cat.png 파일을 display 하고 싶다면 아래와 같이 하시면 됩니다.
local catImage = display.newImage( "Images/cat.png", system.DocumentsDirectory, 0, 0 )
Note : baseDirectory 파라미터가 필요한 system.pathForFile 을 API call 에서 사용하지 않은 점을 유의하세요. (e.g., display.newImage, display.newImageRect, audio.loadSound, etc.)
만약 같은 디렉토리의 readme.txt 파일을 열어보고 싶으시면 system.pathForFile 을 사용해서 아래와 같이 하세요.
local path = system.pathForFile( "Images/readme.txt", system.DocumentsDirectory ) local fileHandle = io.open( path ) -- You can now use fileHandle:read or fileHandle:write to read or write the file.
해당 파일이 있다면 fileHandle 은 nil 이 아니겠죠. 그 다음은 아래 질문과 연결 되게 됩니다.
3. How do you test that a file exists in a folder or sub-folder?
해당 폴더나 서브폴더 안에 특정 파일이 존재하는지를 보기 위해 아래와 같이 코딩 하실 수 있습니다. 이 함수를 call 하기 전에 서브폴더 이름을 file 이름에 append 하는 것을 잊지 마세요.
---------------------------------------------------------------------------------- -- doesFileExist -- -- Checks to see if a file exists in the path. -- -- Enter: name = file name -- path = path to file (directory) -- defaults to ResourceDirectory if "path" is missing. -- -- Returns: true = file exists, false = file not found ---------------------------------------------------------------------------------- -- function doesFileExist( fname, path ) local results = false local filePath = system.pathForFile( fname, path ) -- filePath will be nil if file doesn't exist and the path is ResourceDirectory -- if filePath then filePath = io.open( filePath, "r" ) end if filePath then print( "File found -> " .. fname ) -- Clean up our file handles filePath:close() results = true else print( "File does not exist -> " .. fname ) end print() return results end
위의 함수가 어떻게 call 되는지 보겠습니다.
-- Checking for file in Documents directory local results = doesFileExist( "Images/cat.png", system.DocumentsDirectory ) -- or checking in Resource directory local results = doesFileExist( "Images/cat.png" )
4. How do you copy a file to a sub-folder?
아래 코드는 파일을 A 폴더에서 B 폴더로 copy 하는 예제 입니다. 흔히 사용하는 방법은 파일을 카피하기 위해 Resource 디렉토리에서 Document 디렉토리로 옮기는 겁니다.
이 함수를 사용하기 전에 해당 서브 폴더들이 있어야 합니다.
---------------------------------------------------------------------------------- -- copyFile( src_name, src_path, dst_name, dst_path, overwrite ) -- -- Copies the source name/path to destination name/path -- -- Enter: src_name = source file name -- src_path = source path to file (directory), nil for ResourceDirectory -- dst_name = destination file name -- overwrite = true to overwrite file, false to not overwrite -- -- Returns: false = error creating/copying file -- nil = source file not found -- 1 = file already exists (not copied) -- 2 = file copied successfully ---------------------------------------------------------------------------------- -- function copyFile( srcName, srcPath, dstName, dstPath, overwrite ) local results = false local srcPath = doesFileExist( srcName, srcPath ) if srcPath == false then -- Source file doesn't exist return nil end -- Check to see if destination file already exists if not overwrite then if fileLib.doesFileExist( dstName, dstPath ) then -- Don't overwrite the file return 1 end end -- Copy the source file to the destination file -- local rfilePath = system.pathForFile( srcName, srcPath ) local wfilePath = system.pathForFile( dstName, dstPath ) local rfh = io.open( rfilePath, "rb" ) local wfh = io.open( wfilePath, "wb" ) if not wfh then print( "writeFileName open error!" ) return false -- error else -- Read the file from the Resource directory and write it to the destination directory local data = rfh:read( "*a" ) if not data then print( "read error!" ) return false -- error else if not wfh:write( data ) then print( "write error!" ) return false -- error end end end results = 2 -- file copied -- Clean up our file handles rfh:close() wfh:close() return results end
아래에 readme.txt 파일을 Resource 에서 Documents 디렉토리에 복사하는 방법이 있습니다.
copyFile( "readme.txt", nil, "readme.txt", system.DocumentsDirectory, true ) local catImage = display.newImage( "cat.png", system.DocumentsDirectory, 0, 0 )
5. What are the Android restrictions concerning files?
코로나에서의 File access 는 해당 운영체제(Operating System) 에 기반해서 이루어 집니다. 즉 플랫폼에 의존적인 거죠. iOS 디바이스에서는 Resource 디렉토리(main.lua 가 있는 디렉토리) 에 access 하실 수 있습니다. 그외에 Documents 그리고 Temporary 디렉토리들에 access 하실 수 있죠. 안드로이드에서는 Resource 디렉토리에 제한이 있습니다. 왜냐하면 그 디렉토리는 실제 디렉토리가 아니기 때문이죠. 파일들은 zip 파일로 압축돼 있습니다. 코로나는 audio와 image API들을 사용해서 직접 이미지와 오디오를 로딩할 수 있도록 해 줍니다. 하지만 I/O API를 사용해서 Resource 파일들에 접근하는 것은 한계가 있습니다.
안드로이드의 이러한 제한사항 때문에 다른 디렉토리에 카피할 Resouce 디렉토리 내의 파일을 옮긴다면 resource 디렉토리에 있는 파일 이름을 바꾸어야 합니다. 그래야 file I/O API에 의해 접근 될 수 있습니다. 예를 들어 이미지 파일을 Resource 에서 documents 디렉토리로 옮기고 싶다면 다른 확장자를 가진 파일로 이름을 바꾸셔야 합니다. 그래야 접근할 수 있습니다. cat.png를 cat.png.txt 로 바꾼 후 카피할 수 있습니다.
아래에 안드로이드에서 어떻게 cat.png 파일을 Document 디렉토리로 복사하는지 알려주는 예제가 있습니다. (assuming it was stored as cat.png.txt)
copyFile( "cat.png.txt", nil, "cat.png", system.DocumentsDirectory, true ) local catImage = display.newImage( "cat.png", system.DocumentsDirectory, 0, 100 )
안드로이드에서 Resource 디렉토리 안에 있는 것 중 읽을 수 없는 확장자들 : html, htm, 3gp, m4v, mp4, png, jpg, and rtf
위 방법은 모든 플랫폼에서 사용 가능합니다. 그러니 안드로이드에서 제대로 돌아가면 어디서든지 돌아갑니다.
오늘은 여기까지 입니다. 유익한 시간이었기를 바랍니다.
'Corona SDK > Corona SDK TIPs' 카테고리의 다른 글
수요일의 FAQ : Runtime Error Listener (2) | 2013.03.19 |
---|---|
loadSoundLibrary : 사운드 파일들을 간편하게 관리하기 (0) | 2013.03.11 |
런타임 에러 처리하기 (0) | 2013.03.07 |
수요일의 FAQ: 코로나 런타임 에러 관련 (0) | 2013.03.06 |
Corona Tip from Facebook : 스토리보드 scene 을 떠날 때.... (0) | 2013.02.01 |
FAQ: 맥 시뮬레이터 업데이트 내용들 (0) | 2013.01.31 |
간단하게 디버그용 print 구문들 실행되지 않도록 하기 (0) | 2013.01.23 |
FAQ Wednesday : Custom Fonts 사용하기 (0) | 2013.01.18 |
Corona tip: Shuffle it! (0) | 2013.01.10 |
Corona TIP : display.remove()와 object:removeSelf() 의 차이 (0) | 2013.01.10 |