반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형
Posted on . Written by



수요일 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


위 방법은 모든 플랫폼에서 사용 가능합니다. 그러니 안드로이드에서 제대로 돌아가면 어디서든지 돌아갑니다.


오늘은 여기까지 입니다. 유익한 시간이었기를 바랍니다.

반응형