FileManager — iOSファイルシステムの操作

著者: IT Sectr 公開日: 2026-07-09 読了時間: 9 分

FileManagerはFoundationフレームワークのクラスで、iOS、macOS、その他のAppleプラットフォームのファイルシステムを操作するためのインターフェースを提供します。ファイルやディレクトリの作成、読み取り、移動、削除、メタデータやアクセス権限の管理が可能です。iOSでは、すべてのFileManager操作はアプリのSandboxによって制限されています。Apple Developer Documentation(2026)によると、FileManagerはスレッドセーフであり、バックグラウンドスレッドから使用できますが、すべてのファイルシステム操作はサンドボックスとSecurity-Scoped Bookmarksのアクセス権限を考慮して実行する必要があります。

重要なポイント

  • FileManagerはファイルシステム操作(読み取り、書き込み、移動、削除)のためのFoundationのメインクラスです。
  • SandboxはFileManagerのアクセスをアプリのディレクトリ(Documents、Library、tmp、App Group)のみに制限します。
  • URLベースAPI(fileManager.urls)は、モダンアプリケーションではStringベース(NSHomeDirectory)よりも推奨されます。
  • FileManagerDelegateは、shouldMoveItemAtやshouldRemoveItemAtを通じてファイル操作の追跡と制御を可能にします。
  • iCloud Driveは、ubiquityContainerが有効で適切なentitlementsが設定されている場合、FileManagerを通じて利用可能です。

FileManagerとは

FileManagerはFoundationフレームワークのシングルトンクラスで、すべてのAppleプラットフォームでファイルシステムと対話するための統一APIを提供します。FileManager.defaultを通じて、またはカスタムデリゲートでインスタンスを作成して利用できます。

クラスの主な機能には、ファイルの存在確認(fileExists)、ディレクトリ作成(createDirectory)、コピーと移動(copyItem、moveItem)、削除(removeItem)、属性取得(attributesOfItem)、ディレクトリ内容取得(contentsOfDirectory)が含まれます。FileManagerはデータシリアライゼーションのためにNSData、String、JSONEncoder/Decoderと密接に関連しています。

FileManagerはスレッドセーフです。Appleは異なるスレッドからの安全なメソッド呼び出しを保証しています。ただし、ファイルシステム操作は大きなファイルでは低速になる可能性があるため、Appleはバックグラウンドキュー(DispatchQueue.global)で実行し、FileManagerDelegateメソッドを呼び出して進捗を報告することを推奨しています。

swift
let fileManager = FileManager.default
let documentsURL = fileManager.urls(
    for: .documentDirectory,
    in: .userDomainMask
).first!

let fileURL = documentsURL.appendingPathComponent("data.plist")

if fileManager.fileExists(atPath: fileURL.path) {
    print("File exists at \(fileURL.path)")
}

iOSアプリの主要ディレクトリ

各iOSアプリには、Sandbox内でFileManagerを通じてアクセス可能な3つの主要ディレクトリがあります:Documents、Library、tmp。それぞれに独自の目的とバックアップルールがあり、App Storeレビューを通過するために遵守することが重要です。

Documents — 起動間で保持され、iCloudにバックアップされるユーザーデータ用。 Library — アプリファイル用:キャッシュ(Caches)、設定(Preferences)、データベース(Application Support)。 tmp — アプリ起動間でシステムがいつでも削除できる一時ファイル用。

ディレクトリFileManager URLバックアップ用途
Documents.documentDirectoryありユーザーデータ、ファイル、エクスポート
Library/Caches.cachesDirectoryなし画像キャッシュ、一時データ
Library/Preferences.libraryDirectory + "Preferences"ありUserDefaults、アプリ設定
Library/Application Support.applicationSupportDirectoryありデータベース、CoreData、Realm
tmp.tmpDirectory(NSTemporaryDirectory)なし一時セッションファイル

Appleのルール:ファイルがインターネットから復元可能または再作成可能な場合 — Cachesに保存(バックアップなし)。ファイルにユーザーデータが含まれる場合 — Documentsに保存(バックアップあり)。不適切なファイル配置はアプリ拒否の一般的な理由の1つであり、AppleはStorageおよびiCloud Backup Guidelinesの準拠をチェックします。

ファイルの読み書き

FileManager自体はファイル内容を読み取るメソッドを提供しません — その場合はNSData(contentsOf)、String(contentsOf)、またはFileHandleメソッドを使用します。FileManagerはファイルの管理(存在確認、移動、コピー、削除)を担当します。

データを書き込むにはcreateFile(atPath:contents:attributes:)メソッドまたは高レベルAPI(data.write(to:)、JSONEncoder.encode、PropertyListEncoder)を使用します。FileManagerは大きなファイルのストリーミング読み書きのためのFileHandleも提供しており、ファイル全体をメモリにロードしません。

swift
struct UserSettings: Codable {
    let username: String
    let isDarkMode: Bool
    let fontSize: Int
}

let settings = UserSettings(
    username: "developer",
    isDarkMode: true,
    fontSize: 16
)

// JSONをDocumentsに書き込む
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(settings)
let url = documentsURL.appendingPathComponent("settings.json")
try data.write(to: url, options: .atomic)

// JSONを読み込む
let loadedData = try Data(contentsOf: url)
let loadedSettings = try JSONDecoder()
    .decode(UserSettings.self, from: loadedData)

書き込み時はoptions: .atomicを使用します — これにより書き込み失敗時にファイルが破損しないことが保証されます。データは最初に一時ファイルに保存され、その後アトミックにターゲットパスに移動されます。大きなファイルを読み取るには、.readingModeでFileHandleを使用し、メモリ消費を制御しながらデータをチャンクで読み取ります。

ディレクトリ管理

FileManagerは完全なディレクトリ管理のためのメソッドを提供します:createDirectory(withIntermediateDirectoriesによる中間フォルダ作成)、contentsOfDirectory(ファイル一覧取得)、enumeratorAt(再帰的走査)、subpathsOfDirectory(ディレクトリ内のすべてのパス)。

enumeratorAtメソッドはDirectoryEnumeratorを返し、すべての内容をメモリにロードせずに大きなディレクトリを効率的に走査できます。skipDescendantsによるフィルタリングをサポートし、追加のファイルシステムクエリなしに各アイテムの属性を提供します。

swift
// 再帰的ディレクトリ走査
if let enumerator = fileManager.enumerator(
    at: documentsURL,
    includingPropertiesForKeys: [.fileSizeKey, .isDirectoryKey]
) {
    for case let fileURL as URL in enumerator {
        let attrs = try fileURL.resourceValues(
            for: [.fileSizeKey, .isDirectoryKey]
        )
        if attrs.isDirectory == false {
            let size = attrs.fileSize ?? 0
            print("File: \(fileURL.lastPathComponent), Size: \(size) bytes")
        }
    }
}

ディレクトリを削除するにはremoveItem(at:)を使用します。警告:iOSでのディレクトリ削除は元に戻せません — macOSのようにファイルはゴミ箱に入りません。削除前にそのディレクトリのファイルが不要になったことを確認し、バックグラウンドスレッドで操作を実行してください。多数のファイルを削除するとUIがブロックされる可能性があります。

FileManagerとiCloud

FileManagerはURLForUbiquityContainerIdentifierメソッドを通じてiCloud Driveと統合され、アプリのiCloudディレクトリのURLを返します。これにはプロジェクトでiCloud機能を有効にし、適切なentitlementを追加する必要があります。

iCloudファイルは自動的に同期されますが、FileManagerは手動制御のためのメソッドを提供します:startDownloadingUbiquitousItemはダウンロードを強制し、evictUbiquitousItemはローカルコピーを削除し、urlOfItem(at:)はiCloudファイルのローカルURLを返します。NSMetadataQueryはiCloud内のファイル検索に使用されます。

重要な制限:iCloud DriveはDocumentsディレクトリのファイルではサポートされていません — ubiquityContainer内のファイルのみが対象です。DocumentsをiCloudで同期しようとしないでください。少量のデータにはNSUbiquitousKeyValueStore、複雑な構造にはCore Data with CloudKitを使用してください。

FileManagerのパフォーマンス

FileManagerの操作は、特に低速なフラッシュメモリを搭載したデバイスではコストがかかる場合があります。Appleの主な推奨事項には、すべてのファイル操作をバックグラウンドキューで実行すること、fileExistsAtPathの呼び出しを最小限にすること、結果をキャッシュすることが含まれます。

fileExistsメソッドはstat()システムコールを実行し、比較的低速です。読み取り前にファイルの存在を確認する場合、直接読み取りを試みてエラーを処理する方が良いでしょう — 同じstatを実行しますが、二重のシステムコールを回避できます。一括チェックには、resourceValuesとともにenumeratorAtを使用します。

大量データを最適化するには:

  • 大きなファイルのストリーミング処理にはFileHandleを使用
  • 頻繁に使用するディレクトリのfileManager.urls結果をキャッシュ
  • メインスレッドのブロックを避け、細粒度キューでバッチ操作を実行
  • 複数スレッドからの安全なアクセスにはCoordinatedFileManagerを使用

Apple Instrumentsはファイル操作のプロファイリング用にFile Activityテンプレートを提供しています。これを使用してボトルネックを特定します — 例えば、ループ内での頻繁なfileExists呼び出しやメインスレッドでの書き込み操作などです。最も一般的なパフォーマンス問題は、アプリ終了時の大きなファイルの同期的書き込みに関連しています。

よくある質問

iOSのFileManagerとは?

FileManagerはAppleファイルシステムを操作するためのFoundationフレームワークのクラスです。ファイルとディレクトリの作成、読み取り、移動、削除のためのAPIを提供します。iOSでは、Security-Scoped Bookmarksを除き、その操作はアプリのSandbox内に制限されます。

iOSでFileManagerを通じてアクセスできるディレクトリは?

Documents — iCloudバックアップ付きユーザーデータ。Library/Caches — バックアップなしのキャッシュ。Library/Application Support — データベース。tmp — 一時ファイル。App Group Container — 同じグループのアプリ間で共有データ用。

FileManagerでDocumentsへのパスを取得するには?

FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).firstを呼び出します。このメソッドは現在のアプリのSandbox内のDocumentsディレクトリへの絶対パスを含むURLを返します。存在確認にはfileExists(atPath:)を使用します。

FileManagerを通じて他のアプリのファイルにアクセスできますか?

いいえ、iOSのSandboxは他のアプリケーションのファイルシステムへのアクセスを防ぎます。例外:App Groups(同じ開発者のアプリ間の共有ディレクトリ)とSecurity-Scoped Bookmarks(UIDocumentPickerとiCloud Driveを介したファイルアクセス)。

FileManagerで安全にファイルを書き込むには?

書き込み時に.atomicオプションを使用します — データは最初に一時ファイルに保存され、その後アトミックにターゲットパスに移動されます。これにより書き込み失敗時のファイル破損を防ぎます。大きなデータの場合は、1〜2MBのチャンク書き込みでFileHandleを使用します。

まとめ

  • FileManagerはiOSのすべてのファイルシステム操作(存在確認から再帰的ディレクトリ走査まで)のためのFoundationの中心的なクラスです。
  • Documents、Library、tmp — 異なるバックアップルールとライフサイクルを持つ3つの主要なアプリディレクトリです。
  • URLベースAPIは、SandboxおよびSecurity-Scoped Bookmarksとの互換性のためにStringベースのパスよりも推奨されます。
  • FileHandleとストリーミング処理は、メモリオーバーフローなしで大きなファイルを扱う唯一の方法です。
  • FileManagerDelegateはshouldメソッドを通じて移動、コピー、削除操作を制御できます。
  • iCloud統合はubiquityContainerとNSMetadataQueryを通じてクラウドファイルの操作が可能です。
  • パフォーマンスはファイル操作において重要です — バックグラウンドキューで実行し、fileExistsの呼び出しを最小限にします。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください