티스토리 뷰

공부

File System Programming Guide

Zedd0202 2018. 2. 28. 15:09
반응형

File System Programming Guide를 공부해봅시댜.

도큐먼트는 여기참고 할거에요.



File System Programming Guide



파일시스템은 데이터 파일, App 및 OS와 관련된 영구 저장소를 처리합니다. 따라서 파일 시스템은 모든 프로세스에서 사용되는 기본 리소스 중 하나입니다.

APFS는 mac OS, iOS, watchOS 및 tvOS의 기본 파일 시스템입니다. (APFS을 잘 모르신다면 <>글을 참고해주세요 XD)

기본 디렉토리 구조는 iOS와 macOS에서 비슷하지만 각 시스템이 앱과 사용자 데이터를 구성하는 방식에는 차이가 있습니다.


파일 시스템과 상호 작용하는 코드를 작성하기 전에, 먼저 파일 시스템의 구성과 코드에 적용되는 규칙에 대해 약간 이해해야 합니다. 

적절한 보안 권한이 없는 디렉토리에 파일을 쓸 수 없다는 기본 교의(tenet)외에, App도 좋은 시민이 되고 적절한 장소에 파일을 넣어야 합니다. 

파일을 저장하는 위치는 플랫폼에 따라 다르지만 중요한 목표는 사용자의 파일을 쉽게 검색 할 수 있도록 하고, 코드에서 내부적으로 사용하는 파일이 사용자의 방해를 받지 않도록 하는 것입니다.


중요한 부분은 마지막줄이죠? 일단 중요한건, 그니까 우리가 이 File System Programming Guide를 공부하는건 어케어케 파일을 잘 사용하고 보안적으로 잘 사용하자 이거죠.


 About the iOS File System(iOS에서의 File System에 관해)

iOS 파일 시스템은 독자적으로 실행되는 앱을 대상으로 합니다. 시스템을 간단하게 유지하기 위해, iOS기기 사용자는 파일 시스템에 직접적으로 접근 할 수 없으므로 App은 이 규칙을 준수해야 합니다. (간접적으로는 접근이 가능)


 iOS Standard Directories: Where Files Reside
(iOS표준 디렉토리 : 파일이 있는 곳)
보안을 위해 iOS앱과 파일 시스템의 사용작용은 Sandbox디렉토리에 있는 디렉토리로 제한이 됩니다.(Sandbox를 잘 모르신다면 < Apple의 Sandbox정책과 Files 앱 >를 참고해주세요.)
새 App을 설치하는 동안, 설치 프로그램은 Sandbox디렉토리 내에 App용 컨테이너 디렉토리를 만듭니다. 각 컨테이너 디렉토리에는 특정 역할이 있습니다.
Bundle 컨테이너 디렉토리는 앱의 Bundle을 보유하고
Data 컨테이너 디렉토리는 앱과 사용자 모두에 대한 데이터를 보유합니다. 이 디렉토리는 앱이 데이터를 정렬하고 구성하는 데 사용할 수 있는 여러 하위 디렉토리로 더 나뉩니다. 앱은 런타임에 추가 컨테이너 디렉토리(예 : iCloud 컨테이너)에 대한 접근을 요청할 수도 있습니다. 



자. 위 그림이 App의 Sandbox 디렉토리를 보여주는 그림입니다. (App 디렉토리를 다운 받는 방법은 < 내 App의 데이터 보기 >글을 참고해주세요.)


App은 일반적으로 컨테이너 디렉토리 외부에서 파일에 접근하거나 만들 수 없습니다. (=외부에서 앱 내의 디렉토리에 접근하거나 파일을 만들 수 없다)

이 규칙의 한가지 예외는 앱이 Public 시스템 인터페이스를 사용하여 사용자의 연락처나 음악과 같은 항목에 접근하는 경우입니다.


이 Sandbox디렉토리 안에 있는 하위 디렉토리를 몇가지 알려드릴게요.


● AppName.app : 이건 App의 Bundle이에요. 이 디렉토리(.app이 왜 디렉토리야..?라는 궁금증이 드실 수 있겠지만..디렉토리입니다. 지금부터 말할거는 다 App Sandbox내에 있는 디렉토리를 말씀드릴거게요.) 암튼 이 디렉토리는 앱과 모든 리소스를 포함합니다. 이 디렉토리에는 write를 할 수 없습니다. 변조를 방지하기 위해 Bundle 디렉토리는 App 설치시 서명됩니다. 이 디렉토리에 write를 하게 되면, 서명이 변경되고, App이 launch되지 않습니다. 그러나 App Bundle에 저장된 모든 리소스에 대한 읽기 전용 접근 권한은 얻을 수 있습니다. 

이 디렉토리의 내용은 iTunse또는 iCloud에 의해 백업되지 않습니다. 그러나 iTunes는 App Store에서 구입 한 모든 응용 프로그램의 초기 동기화를 수행합니다.


● Documents/ : 이 디렉토리를 사용하여 사용자 생성 Contents를 저장하세요. 이 디렉토리의 내용은 파일 공유를 통해 사용자가 사용 할 수 있습니다. 따라서 이 디렉토리에는 사용자에게 공개 할 수 있는 파일만 포함되어야 합니다. 이 디렉토리의 내용은 iTunes 및 iCloud에 의해 백업됩니다.


● Documents/Inbox :  이 디렉토리를 사용하여 앱이 외부 엔티티에서 열도록 요청한 파일에 접근합니다. 특히 메일(mail)은 이 디렉토리에 앱과 관련된 이메일 첨부 파일을 저장합니다. Document interaction controllers는 파일을 파일 App에 배치할 수도 있습니다.
앱은 이 디렉토리의 파일을 읽고, 삭제 할 수는 있지만 새 파일을 만들거나, 기존파일에  write를 할 수는 없습니다. 사용자가 이 디렉토리의 파일을 편집하려고 하면, 변경하기전에 디렉토리에서 앱을 이동해야 합니다. 이 디렉토리의 내용은 iTunes 및 iCloud에 의해 백업됩니다.

● Library/ : 이것은 사용자 데이터 파일이 아닌, 파일의 최상위 디렉토리 입니다. 일반적으로 여러 표준 하위 디렉토리 중 하나에 파일을 저장합니다. iOS App은 일반적으로 Application Support 와 Caches의 하위 디렉토리를 사용합니다. 그러나 사용자 지정 하위 디렉토리를 만들 수 있습니다.
사용자에게 노출시키지 않으려는 파일에는 라이브러리 서브 디렉토리를 사용하세요. 앱에서 사용자 데이터 파일 용으로 이러한 디렉토리를 사용하지 않아야 합니다.
라이브러리 디렉토리의 Contents (Caches 서브 디렉토리 제외)는 iTunes 및 iCloud에 의해 백업됩니다.

tmp/ : 이 디렉토리를 사용하여 앱 실행 사이에 유지할 필요가 없는 임시파일을 작성하세요. 더 이상 필요하지 않으면 앱에서 이 디렉토리의 파일을 삭제해야합니다. 그러나 앱이 실행되고 있지 않을 때, 시스템에서 이 디렉토리를 제거할 수 있습니다. 이 디렉토리의 Contents는 iTunes 또는 iCloud에 의해 백업되지 않습니다. 


Where You Should Put Your App’s Files(앱의 파일을 어디에 두어야 하는지)


iOS 디바이스의 동기화 및 백업 프로세스가 오래 걸리지 않도록 하려면, 파일을 저장할 위치를 선택하세요.
대용량 파일을 저장하는 App은 iTunse또는 iCloud로 백업하는 과정을 지연시킬 수 있습니다. 또한 이러한 App은 저장공간을 많이 차지하므로, 사용자가 앱을 삭제하거나 해당 앱의 데이터를 iCloud에 백업하지 못하도록 유도할 수 있습니다. 이를 염두에 두고, 다음 가이드라인에 따라 앱 데이터를 저장해야합니다.

● Documents /에 사용자 데이터를 입력하세요. 사용자 데이터에는 일반적으로 사용자에게 공개하려는 파일(사용자가 생성, 가져오기, 삭제, 또는 편집할 수 있는 모든 파일)이 포함됩니다. 그리기 App의 경우, 사용자 데이터에는 사용자가 만들 수 있는 모든 그래픽 파일이 포함됩니다. 비디오 및 오디오 App에는 사용자가 나중에 시청하거나 듣기위해 다운로드한 파일도 포함 될 수 있습니다.
==> 사용자 데이터는 다 여기 넣으라는 말

● Library/Application support/ 디렉토리에 App에서 만든  support 파일을 넣으세요. 일반적으로 이 디렉토리는 앱이 실행하는데 사용하지만, 사용자에게 숨겨져 있어야 하는 파일을 포함합니다. 이 디렉토리에는 데이터파일, 구성파일, 템플릿 및 앱 번들에서 로드된 수정 된 버전의 리소스도 포함될 수 있습니다.

●  Documents / 와 Application Support / 디렉토리의 파일은 기본적으로 백업된다는 점을 기억하세요. NSURLIsExcludedFromBackupKey를 사용하여 백업에서 파일을 제외할 수 있습니다. (문서에는 Objc소스만..있네요.. )


  1. var resourceValues:URLResourceValues = URLResourceValues()

    resourceValues.isExcludedFromBackup = true

      do{

           try fileUrl.setResourceValues(resourceValues)

         }


여기서 fileUrl은 백업에서 제외시키고 싶은 파일의 URL입니다. 백업에서제외하겠니?니까 true면 백업에서 제외하겠다는 소리입니다. 

아무튼 계속해서..

다시 만들거나 다운로드 할 수 있는 파일은 백업에서 제외해야합니다. 이는 대용량 미디어 파일에 특히 중요합니다. App에서 비디오 또는 오디오 파일을 다운로드 하는 경우, 해당 파일이 백업에 포함되어 있지 않은지 확인하세요.


임시 데이터를 tmp/ 디렉토리에 저장하세요. 임시 데이터는 오랜 기간동안 유지 할 필요가 없는 모든 데이터로 구성됩니다. 사용자의 디바이스에서 공간을 계속 소비하지 않도록 파일을 삭제해야합니다. 앱이 실행되고 있지 않을 때, 시스템에서 주기적으로 파일을 삭제합니다. 


Library / Caches / 디렉토리에 데이터 캐시 파일을 저장합니다. 캐시 데이터는 임시 데이터보다 오래 지속되어야 하지만, Support파일이 아닌 모든 데이터에 사용될 수 있습니다. 일반적으로 App은 캐시 데이터가 제대로 작동하는 것을 요구하지 않지만, 캐시 데이터를 사용하여 성능을 향상시킬 수 있습니다. 캐시 데이터의 예로는 DB 캐시 파일과 일시적으로 다운로드 할 수 있는 Contents가 있습니다. 시스템에서 Caches/디렉토리를 삭제하여 디스크 공간을 비울 수 있으므로, 앱이 필요에 따라 이러한 파일을 다시 만들거나, 다운로드 할 수 있어야 합니다.

(막 어떤 앱 보면 캐쉬삭제라 되어있고, 몇메가 쌓였다고 보여주잖아요? 그게 이 디렉토리에 있는 파일을 말하는 것 같아요)



Mac OS파일 시스템은 건너뛰겠습니다.


The iCloud File Storage Container

착각을 하시면 안됩니다. 어 내 App에서 iCloud Drive에 파일을 저장할 수 있나 ㅎ?
위에서 말씀드렸듯이


내 App의 Sandbox안에 iCloud 저장소가 따로 있습니다.

이 iCloud 컨테이너에 대해서 자세하게 알아봅시다.


iCloud는 iCloud를 사용하는 App의 파일을 저장하기 위한 구조화 된 시스템을 제공합니다.

App에는 기본 파일을 저장하기 위한 기본 iCloud 컨테이너 디렉토리가 있습니다. 또한 app entitlements에 나열된 보조 iCloud 컨테이너 디렉토리에 접근 할 수 있습니다.

각 컨테이너 디렉토리 안에는 파일이 "documents"와 data로 분리되어있습니다. Documents의 하위 디렉토리(또는 하위 디렉토리 중 하나)에 있는 모든 파일 또는 파일 패키지는 개별적으로 삭제할 수 있는 별도의 문서로 사용자에게 전달됩니다. 

사용자가 App의 사용자 인터페이스(UI)에서 만들고 볼 수 있는 문서(예 : Pages, Numbers 및 Keynote의 문서 브라우저)는 Documents디렉토리에 저장해야합니다. 



앱이 사용자가 직접 보거나 수정하기를 원하지 않는 항목은 모두 Documents디렉토리 외부에 배치해야합니다. 앱은 컨테이너 디렉토리에 하위 디렉토리를 만들 수 있으므로 원하는대로 비공개 파일을 정렬 할 수 있습니다.


앱은 로컬 파일 및 디렉토리를 만드는 것과 똑같은 방식으로 iCloud 컨테이너 디렉토리에 파일 및 디렉토리를 만듭니다. 모든 파일의 속성이 저장됩니다. 확장 된 속성을 파일에 추가하면, 해당 속성이 iCloud 및 사용자의 다른 기기에도 복사됩니다.

iCloud 컨테이너를 사용하면 문서 형식을 만들지 않고도 쉽게 접근 할 수 있는 Key-Value쌍을 저장할 수 있습니다.


How the System Identifies the Type of Content in a File(시스템이 파일이 내용 타입을 식별하는 방법)

이 내용은 알아두시면 굉장히 좋습니다 File Provider를 하시면 나오는 내용이에요.
시작할게요!

파일의 내용 타입을 식별하는데 두가지 기본 기술이 있습니다.


  • Uniform Type Identifiers (UTIs)

  • Filename extensions


UTIs는 "type"을 가진 것으로 간주되는 엔티티 클래스를 고유하게 식별하는 문자열입니다.
UTIs는 모든 App 및 서비스에서 인식하고 의존할 수 있는 데이터에 대한 일관된 식별자를 제공합니다. 파일 및 디렉토리 뿐만아니라 모든 타입의 데이터를 나타낼 수 있기 때문에 대부분의 다른 기술보다 유연성이 뛰어납니다. UTIs의 예는 다음과 같습니다.

public.text - 텍스트 데이터를 식별하는 공용 타입입니다.
public.jpeg - JPEG 이미지 데이터를 식별하는 공용 타입입니다.
com.apple.bundle - 번들 디렉토리를 식별하는 Apple타입입니다.
com.apple.application-bundle - 번들 된 앱을 식별하는 Apple타입입니다.
파일 타입을 지정하는 데 UTI-기반 인터페이스를 사용할 수 있을 때마다 다른 인터페이스보다 이 UTI기반 인터페이스를 선호해야합니다. 


주어진 파일에 대해 시스템이 UTI를 결정하는 한 가지 방법은 파일 이름 확장명을 보는 것입니다. 파일 이름 확장자는 파일의 끝에 추가되고 주 파일 이름과 마침표로 구분된 문자열입니다.  고유 한 각 문자열은 특정 타입의 파일을 식별합니다. 예를들어, .strings확장자는 localize할 수 있는 문자열 데이터가 있는 리소스를 파일을 식별하고, .png확장자는 휴대용 네트워크 그래픽 형식의 이미지 데이터가 있는 파일을 식별합니다.




Security: Protect the Files You Create

모든 사용자 데이터와 시스템 코드는 디스크 어딘가에 저장되므로 파일과 파일 시스템의 무결성을 보호하는 것이 중요한 작업입니다. 이러한 이유로 컨텐츠를 보호하고 다른 프로세스에서 컨텐츠를 도난당하거나 손상시키지 않도록 하는 몇가지 방법이 있습니다.
이는  Secure Coding Guide를 참고하세요.


Sandboxes Limit the Spread of Damage(Sandbox가 피해확산을 제한합니다.)


했던말 또함 여기서....
iOS 및 MacOS 10.7이상에서는 Sandbox가 App이 기록하지 않아야 하는 파일 시스템 부분에 쓰지 못하게 합니다.
Sandbox처리된 각 앱은 하나 이상의 컨테이너에 쓸 수 있습니다. 앱은 다른 앱의 컨테이너 또는 Sandbox 외부의 대부분의 디렉토리에 쓸 수 없습니다.
이러한 제한은 앱의 보안이 침해당했을 때 발생할 수 있는 잠재적인 피해를 제한합니다.
iOS앱 개발자는 설치 시간에 시스템이 자동으로 앱을 실행하기 때문에 앱을 Sandbox에 명시적으로 넣을 필요가 없습니다.


Permissions and Access Control Lists Govern All Access to Files


파일 및 디렉토리에 대한 접근은 접근제어목록(ACL)과 BSD권한의 혼합으로 제어됩니다. 접근 제어 목록은 파일이나 디렉토리에 대해 수행 할 수 있는 작업과 수행 할 수 없는 작업을 정확하게 정의하는 세분화된 컨트롤 Set입니다. 접근 제어 목록을 사용하면 개별 사용자에게 주어진 파일 또는 디렉토리에 대한 다양한 접근 레벨을 부여할 수 있습니다. 반대로 BSD권한은 파일의 소유자, 지정한 단일 사용자 그룹 및 모든 사용자 등 세가지 클래스의 사용자에게만 접근 권한을 부여할 수 있습니다. iOS앱은 항상 Sandbox에서 실행되기 때문에 시스템은 각 앱에서 만든 파일에 특정 접근 제어 목록 및 권한을 할당합니다.


Accessing Files and Directories

파일을 열기 전에 먼저 파일 시스템에서 파일을 찾아야 합니다.
시스템 프레임워크는 라이브러리 디렉토리와, 잘 알려진 많은 디렉토리에 대한 참조를 얻기 위한 많은 루틴을 제공합니다. 
알려진 디렉토리 이름에서 URL또는 문자열 기반 경로를 작성하여 수동으로 위치를 지정할 수 도 있습니다.
파일의 위치를 알게 되면 파일에 접근하는 가장 좋은 방법을 계획할 수 있습니다.
파일 타입에 따라 몇가지 옵션이 있을 수 있습니다. 알려진 파일 타입인 경우, 일반적으로 내장된 시스템 루틴을 사용하여 파일 내용을 읽거나 쓰고 사용할 수 있는 객체를 제공합니다. 사용자 정의 파일 타입일 경우, 원시(raw) 파일데이터를 직접 읽어야 할 수도 있습니다.


Choose the Right Way to Access Files

모든 파일을 열고 내용을 바이트 스트림으로 읽을 수 있지만, 그렇게 하는것이 항상 올바른 선택은 아닙니다. macOS 및 iOS는 다양한 유형의 표준 파일 형식 (예 : 텍스트 파일, 이미지, 사운드 및 속성 목록)을 훨씬 쉽게 열 수있는 기본 지원을 제공합니다. 이러한 표준 파일 형식의 경우 파일 내용을 읽고 쓰는 데 더 높은 수준의 옵션을 사용하십시오. 자세한 내용은 여기를 참고해주세요. 

Specifying the Path to a File or Directory


파일이나 디렉토리의 위치를 지정하는 가장 좋은 방법은 NSURL(=URL도 가능)클래스를 사용하는 것입니다. NSString클래스는 Path생성과 관련된 많은 메소드를 가지고 있지만, URL은 파일과 디렉토리를 찾는 더 강력한 방법을 제공합니다. 
네트워크 리소스와도 작동하는 App의 경우, URL은 한 타입의 객체를 사용하여 로컬 파일 시스템이나 네트워크 서버에 있는 아이템을 관리할 수 있음을 의미합니다.

대부분의 URL의 경우, 아이템 Path를 찾을 때 까지 적절한 NSURL메소드를 사용하여 디렉토리 및 파일 이름을 연결하여 URL을 작성합니다. 이 방법으로 작성된 URL은 아이템을 찾기 위해 디렉토리 계층 구조를 탐색하는데 필요한 이름을 저장하기 때문에, 경로 기반 URL(=path-based URL)이라고 합니다.
path-based URL외에도 파일참조를 만들 수 있습니다.

다음 아이템은 user의 Documents디렉토리에 있는 MyFile.txt라는 파일에 대한 유요한 참조입니다.

path-based URLfile://localhost/Users/steve/Documents/MyFile.txt
File reference URL : file:///.file/id=6571367.2773272/
String-based path: /Users/steve/Documents/MyFile.txt

NSURL메소드를 사용하여 URL객체를 만들고, 필요할 때만 File reference URL로 변환합니다. path-based URL은 조작하기 쉽고 디버그하기 쉬우므로 일반적으로 NSFileManager(=FileManager)와 같은 클래스에서 선호됩니다. File reference URL의 이점은 앱 실행중에, path-based URL보다 덜 취약하다는 것입니다. 사용자가 Finder기반에서 파일을 이동하면, 해당 파일을 참조하는 path-based URL이 즉시 유효하지 않게 되고, 새 경로로 업데이트 해야합니다. 그러나 파일이 동일한 디스크의 다른 위치로 이동하는 동안, 고유 ID는 변경되지 않으므로 File reference URL은 유효합니다.
(오..! 좋은 정보..)
중요 : 앱을 실행하는 동안, 안전하게 사용할 수 있지만, 시스템 재부팅시에는 파일의 ID가 변경될 수 있기 때문에 File reference URL은 앱 실행 사이에 저장하고 다시 사용 할 수 없습니다.(엥..) 앱 실행 사이에 파일의 위치를 지속적으로 저장하려면, 북마크를 사용하여 Locating Files Using Bookmarks에 설명된대로 북마크를 만듭니다. 

물론 문자열을 사용하여 파일을 참조해야 할 때가 있습니다. 다행이 NSURL클래스는 path-based URL을 NSString 객체로 변환하거나 NSString에서 변환하는 메소드를 제공합니다. 해당 경로를 사용자에게 표시하거나 URL대신 문자열을 허용하는 시스템 루틴을 호출 할 때, 문자열 기반 경로를 사용할 수 있습니다. NSURL객체와 NSString객체 간의 변환은 NSURL클래스의 absoluteString메소드를 사용하여 수행됩니다.



반응형

'공부' 카테고리의 다른 글

[Clean Code] 5 : 형식 맞추기  (0) 2018.03.16
함수객체? 모나드? map???  (0) 2018.03.06
Apple의 파일시스템. HFS+와 APFS  (0) 2018.02.23
[Clean Code] 4 : 주석  (0) 2018.02.17
Accessibility(접근성)이란?  (0) 2018.02.16