Thursday, January 20, 2011

データの保存 (2) - ホームディレクトリとファイルパス

iPhoneアプリ開発において、データを保存したい場合はどうすればいいのだろう?

今回は様々なデータ保存の手法を取り上げてみます。

バックナンバー
  1. 設定を保存するシンプルな方法
  2. ホームディレクトリとファイルパス
  3. ファイルやディレクトリの操作
  4. いろいろなデータのファイル保存
  5. プロパティリストの利用
  6. ローレベルなファイルアクセス

ホームディレクトリとファイルパス

ファイルにアクセスするにはまずファイルのパスを決定する必要があります。

この記事の内容
  • ホームディレクトリのパス
  • リソースファイルのパス
  • ファイルパスの操作
  • ファイル名の取得
  • ファイルパスの標準化
ホームディレクトリのパス

iOSアプリは、セキュリティー制限により各アプリのホームディレクトリ(/Applications/<GUID>/)以下しかアクセスできません。従って全てのファイルはホームディレクトリ下に保存する必要があります。
ホームディレクトリはNSHomeDirectory()で取得できます。

Tips: ドキュメントディレクトリ下(~/Document)に保存したファイルはiTunesによるバックアップ対象となります。

Note: 実機では ~/Document または ~/tmp 以下のみフルアクセスできます。その他のディレクトリやホームディレクトリ直下は書き込みなどのアクセスが制限されます。

NSString *homeDirectory = [NSString stringWithString:NSHomeDirectory()];

// ドキュメント ディレクトリ
NSString *documentDirectory = [homeDirectory  stringByAppendingPathComponent:@"Documents"];

// 一時ファイル ディレクトリ
NSString *tmpDirectory = [homeDirectory  stringByAppendingPathComponent:@"tmp"];
リソースファイルのパス

XcodeでResourcesに放り込んだファイルはアプリケーションバンドル内(/Applications/<GUID>/<Application Name>.app/)に保存されます。

これらのファイルはNSBundleを利用すると簡単にファイルパスが取得できます。

Note: アプリケーションバンドル内のファイルは読み取り専用です。

// ファイルパスを取得 (LoremIpsum.txt)
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"LoremIpsum" ofType:@"txt"];

// もうひとつの方法
NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *anotherFilePath = [bundlePath stringByAppendingPathComponent:@"Lorem.jpeg"];
ファイルパスの操作

ファイルパスはNSStringのメソッドを利用すると簡単に操作できます。

パスコンポーネントを追加・削除するには stringByAppendingPathComponent, stringByDeletingLastPathComponent を使用します。これらのメソッドを使えばパス区切り文字(スラッシュ)の有無を意識する必要はありません。
ファイル名を取得するには、最後のパスコンポーネントを取得する lastPathComponent が利用できます。
パスを分解するには pathComponents を利用するとパスコンポーネントの配列が取得できます。

// Document Directory
NSString *filePath = [NSString stringWithString:NSHomeDirectory()];
filePath = [filePath stringByAppendingPathComponent:@"Documents"];

// パスコンポーネントの追加
filePath = [[[filePath stringByAppendingPathComponent:@"lorem"]
                      stringByAppendingPathComponent:@"ipsum"]
                     stringByAppendingPathComponent:@"dolor.txt"];

// 最後のパスコンポーネントの取得 (このケースではファイル名を取得)
NSString *fileName =  [filePath lastPathComponent];

// 最後のパスコンポーネントを削除
NSString *directoryPath =  [filePath stringByDeletingLastPathComponent];

// パスコンポーネントを分解
NSArray *components = [filePath pathComponents];
ファイル名の操作

ファイル名から拡張子を削除したり、拡張子のみを抜き出す場合はNSStringのメソッド stringByDeletingPathExtension, pathExtension が利用できます。

NSString *filename = @"LoremIpsum.txt";

// 拡張子を除去
NSString *name = [filename stringByDeletingPathExtension]; // LoremIpsum

// 拡張子を取得
NSString *extension = [filename pathExtension]; // txt
ファイルパスの標準化

NSStringの stringByStandardizingPath メソッドを使用すると、ファイルパスに含まれるシンボリックリンクを展開し、不要なパスコンポーネントを整理できます。具体的には以下のように処理されます。

  • チルダで始まるパス(~/, ~user/)は、ホームディレクトリへのフルパスに置換されます。
  • 空のパスコンポーネント(//)、現在のディレクトリへの参照(./)は削除されます。
  • 絶対パスの場合は親ディレクトリへの参照(../)が実パスに置換されます。相対パスの場合は親ディレクトリへの参照が残ります。
  • パスが/privateで始まる場合で、なおかつこれを除去してもパスが有効に機能する場合(ディレクトリ・ファイルが存在するとき)は除去します。

Note: すべてのシンボリックリンクが展開されるとは限りません。またこのメソッドはURIなどファイルパス以外の文字列には機能しません。

NSString *itemPath = [NSString stringWithString:@"~/./LoremIpsumDolor.txt"];

// ファイルパスを標準化
NSString *standardPath = [itemPath stringByStandardizingPath];
参考サイト

次回

次の記事では「ファイルやディレクトリの操作」について取り上げます。

No comments:

Post a Comment