SwiftでのFileManagerの使い方!10選の詳細なサンプルコード – Japanシーモア

SwiftでのFileManagerの使い方!10選の詳細なサンプルコード

SwiftのFileManagerを使ったサンプルコードのイメージSwift
この記事は約27分で読めます。

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

SwiftはAppleが開発したプログラミング言語で、iOSやmacOSなどのアプリ開発に広く利用されています。

Swiftの強力なライブラリの1つに、ファイルやディレクトリの操作を扱うFileManagerがあります。

この記事では、SwiftのFileManagerの使い方を初心者から中級者向けに10選の詳細なサンプルコードを交えて完全解説します。

Swiftのアプリケーション開発を行っていると、アプリ内でのファイルの操作は避けて通れないテーマとなります。

画像やテキスト、設定ファイルなど、様々なデータを効率よく、安全に操作するための手段としてFileManagerが存在します。

このFileManagerをマスターすることで、アプリ開発の幅が格段に広がります。

●SwiftのFileManagerとは

FileManagerは、SwiftのFoundationフレームワークに含まれるクラスで、ファイルやディレクトリの操作を抽象化して提供します。

これにより、デベロッパーは複雑なファイルシステムの操作を、簡潔で直感的なコードで実現することができます。

○FileManagerの基本的な役割と機能

FileManagerの主な役割は、次のような操作をサポートすることです。

  1. ファイルやディレクトリの作成、読み込み、書き込み、削除
  2. ファイルやディレクトリの属性の取得や設定
  3. ディレクトリ内のファイル一覧の取得
  4. ファイルやディレクトリの移動やリネーム
  5. 特定の条件を満たすファイルやディレクトリの検索

これらの操作を行う際、FileManagerはアプリケーションのサンドボックス内での操作を前提としています。

これはiOSやmacOSのセキュリティポリシーに基づくもので、アプリが他のアプリのデータにアクセスしたり、システム領域に不正にアクセスすることを防ぐための措置です。

また、FileManagerを使用する際は、エラーハンドリングを適切に行うことが重要です。

ファイルの読み込みや書き込み、移動などの操作は、さまざまな理由で失敗する可能性があります。

このような場合、適切なエラーメッセージを表示したり、回復処理を行ったりすることで、ユーザーにとって使いやすいアプリを提供することができます。

●FileManagerの基本的な使い方

Swiftの中で、ファイルやディレクトリの操作を行うときに役立つのが「FileManager」クラスです。

このクラスは、iOS、macOS、watchOS、tvOSといったAppleの各OS上でのファイル操作を効率的に行うためのものです。

FileManagerの使い方を掴むことで、アプリケーションのデータ管理や、ユーザーのデータ処理を柔軟に行うことができます。

○サンプルコード1:ドキュメントディレクトリへのアクセス

FileManagerを使用して、アプリのドキュメントディレクトリへのパスを取得する方法を学びましょう。

import Foundation

let fileManager = FileManager.default
if let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
    print(documentDirectory)
}

このコードでは、FileManager.defaultを使ってデフォルトのFileManagerインスタンスを取得しています。

次に、urls(for:in:)メソッドを使用して、ドキュメントディレクトリのURLを取得しています。

この例では、アプリケーションのドキュメントディレクトリのパスを取得して表示しています。

上記のコードを実行すると、アプリケーションのドキュメントディレクトリのパスがコンソールに出力されます。

このパスはアプリケーションごとに異なるため、自身のアプリで実行した場合のパスと、他のアプリでのパスは異なる点に注意してください。

○サンプルコード2:ファイルの作成と保存

次に、FileManagerを利用して、テキストファイルをドキュメントディレクトリに作成・保存する方法を見てみましょう。

import Foundation

let fileManager = FileManager.default
if let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
    let fileName = "sample.txt"
    let fileURL = documentDirectory.appendingPathComponent(fileName)
    let sampleText = "これはサンプルのテキストです。"

    do {
        try sampleText.write(to: fileURL, atomically: true, encoding: .utf8)
        print("ファイルの保存に成功しました!")
    } catch {
        print("ファイルの保存に失敗しました:\(error)")
    }
}

このコードでは、初めにドキュメントディレクトリのパスを取得しています。

その後、appendingPathComponent(_:)メソッドを使用して、ファイル名を追加して完全なファイルのURLを作成します。

そして、Stringクラスのwrite(to:atomically:encoding:)メソッドを使用して、テキストをファイルに書き込んでいます。

このコードを実行すると、「これはサンプルのテキストです。」という内容のテキストファイルがドキュメントディレクトリに保存されます。

保存が成功した場合、「ファイルの保存に成功しました!」というメッセージがコンソールに表示されます。

保存に失敗した場合は、エラーメッセージが表示されます。

○サンプルコード3:ファイルの読み込み

SwiftのFileManagerを使ってファイルを読み込む方法を解説します。

具体的には、アプリケーションのドキュメントディレクトリに保存されたテキストファイルを読み込み、その内容を文字列として取得します。

このコードでは、FileManagerのインスタンスを取得し、ドキュメントディレクトリへのパスを取得します。

次に、そのディレクトリにある「sample.txt」という名前のファイルを読み込むコードを表しています。

この例では、テキストファイルの内容を取得して、それをコンソールに出力しています。

import Foundation

// FileManagerのインスタンスを取得
let fileManager = FileManager.default

// ドキュメントディレクトリのURLを取得
if let documentsDirectory = try? fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) {
    let fileURL = documentsDirectory.appendingPathComponent("sample.txt")

    do {
        // ファイルの内容を文字列として読み込む
        let content = try String(contentsOf: fileURL, encoding: .utf8)
        print(content)
    } catch {
        print("ファイルの読み込みに失敗しました。")
    }
}

このコードを実行すると、ドキュメントディレクトリに存在する「sample.txt」の内容がコンソールに表示されます。

存在しない場合や、読み込みに問題がある場合は「ファイルの読み込みに失敗しました。」というメッセージが表示されます。

○サンプルコード4:ファイルの移動とリネーム

ファイルやディレクトリの移動、およびリネームの方法を紹介します。

この操作もFileManagerを利用して行います。

このコードでは、ドキュメントディレクトリにある「sample.txt」という名前のファイルを「renamed.txt」に名前を変更しながら、同じディレクトリ内に移動する方法を表しています。

具体的には、moveItem(at:to:)メソッドを使ってファイルを移動およびリネームしています。

import Foundation

let fileManager = FileManager.default

if let documentsDirectory = try? fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) {
    let originalFileURL = documentsDirectory.appendingPathComponent("sample.txt")
    let newFileURL = documentsDirectory.appendingPathComponent("renamed.txt")

    do {
        // ファイルを移動およびリネーム
        try fileManager.moveItem(at: originalFileURL, to: newFileURL)
        print("ファイルを正常に移動およびリネームしました。")
    } catch {
        print("ファイルの移動およびリネームに失敗しました。")
    }
}

このコードを実行すると、ドキュメントディレクトリに存在する「sample.txt」という名前のファイルが「renamed.txt」という新しい名前で同じディレクトリ内に移動されます。

操作に問題があった場合は、「ファイルの移動およびリネームに失敗しました。」というメッセージが表示されます。

●FileManagerの応用例

SwiftでのFileManagerは、単純なファイルの取得や保存だけでなく、さまざまな応用的な操作もサポートしています。

ここでは、SwiftでのFileManagerを使ったいくつかの応用的な操作について、サンプルコードとともに解説します。

○サンプルコード5:特定の拡張子を持つファイルのリストアップ

FileManagerを利用することで、特定の拡張子を持つファイルを効率的にリストアップすることができます。

下記のコードでは、ドキュメントディレクトリ内の.txt拡張子を持つファイルのリストを取得しています。

import Foundation

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

do {
    let fileURLs = try fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil)
    let txtFiles = fileURLs.filter { $0.pathExtension == "txt" }

    for txtFile in txtFiles {
        print(txtFile.lastPathComponent)
    }
} catch {
    print("エラー: \(error)")
}

このコードでは、まずFileManagerのインスタンスを生成しています。

次に、ドキュメントディレクトリのURLを取得して、そのディレクトリ内の全ファイルをcontentsOfDirectoryメソッドで取得します。

その後、取得したファイルURLの中から.txt拡張子を持つものだけをfilterで絞り込み、ファイル名を表示しています。

実行すると、ドキュメントディレクトリ内の.txtファイル名がコンソールに表示されます。

○サンプルコード6:ファイルのコピーと削除

ファイルのコピーや削除もFileManagerを使用して簡単に行うことができます。

下記のコードでは、ドキュメントディレクトリ内のsample.txtというファイルをcopySample.txtとしてコピーした後、元のsample.txtを削除しています。

import Foundation

let fileManager = FileManager.default
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let sampleFileURL = documentDirectory.appendingPathComponent("sample.txt")
let copiedFileURL = documentDirectory.appendingPathComponent("copySample.txt")

do {
    // sample.txtをcopySample.txtとしてコピー
    try fileManager.copyItem(at: sampleFileURL, to: copiedFileURL)

    // sample.txtを削除
    try fileManager.removeItem(at: sampleFileURL)
} catch {
    print("エラー: \(error)")
}

このコードでは、sample.txtのURLとcopySample.txtのURLをそれぞれ取得しています。

copyItemメソッドでファイルのコピーを行い、removeItemメソッドでファイルの削除を行っています。

このコードを実行すると、ドキュメントディレクトリ内にsample.txtは存在せず、copySample.txtとしてコピーされたファイルのみが存在する状態となります。

○サンプルコード7:ディレクトリの操作

SwiftのFileManagerでは、ディレクトリに関する操作も簡単に行うことができます。

ディレクトリの作成、削除、リネームなどの基本的な操作を通じて、ファイルシステムの構造を管理する方法を学びましょう。

import Foundation

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

// ディレクトリの作成
let newDirectoryURL = documentsURL.appendingPathComponent("新しいディレクトリ")
do {
    try fileManager.createDirectory(at: newDirectoryURL, withIntermediateDirectories: true, attributes: nil)
    print("ディレクトリを作成しました。")
} catch {
    print("ディレクトリの作成に失敗しました:\(error)")
}

// ディレクトリの名前の変更
let renamedDirectoryURL = documentsURL.appendingPathComponent("リネーム後のディレクトリ")
do {
    try fileManager.moveItem(at: newDirectoryURL, to: renamedDirectoryURL)
    print("ディレクトリの名前を変更しました。")
} catch {
    print("ディレクトリの名前の変更に失敗しました:\(error)")
}

// ディレクトリの削除
do {
    try fileManager.removeItem(at: renamedDirectoryURL)
    print("ディレクトリを削除しました。")
} catch {
    print("ディレクトリの削除に失敗しました:\(error)")
}

このコードでは、FileManagerを使ってディレクトリの作成、名前の変更、そして削除を行うコードを表しています。

この例では、ドキュメントディレクトリ内に新しいディレクトリを作成し、その後で名前を変更して、最後にそのディレクトリを削除しています。

ディレクトリを作成した際、ディレクトリが既に存在する場合はエラーが発生することがありますので、エラーハンドリングを行っています。

同様に、名前の変更や削除の際もエラーが発生する可能性があるため、do-catch文を用いてエラーハンドリングを実装しています。

このサンプルコードを実行すると、”ディレクトリを作成しました。”、”ディレクトリの名前を変更しました。”、”ディレクトリを削除しました。”のメッセージが表示されるはずです。

○サンプルコード8:ファイルの属性取得

SwiftのFileManagerでは、ファイルやディレクトリの属性情報を取得することができます。

属性情報には、ファイルのサイズ、作成日、最終更新日などのメタデータが含まれます。

import Foundation

let fileManager = FileManager.default
let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first!
let sampleFileURL = documentsURL.appendingPathComponent("サンプル.txt")

do {
    let attributes = try fileManager.attributesOfItem(atPath: sampleFileURL.path)

    if let fileSize = attributes[.size] as? Int64 {
        print("ファイルのサイズは\(fileSize)バイトです。")
    }

    if let creationDate = attributes[.creationDate] as? Date {
        print("ファイルの作成日は\(creationDate)です。")
    }

    if let modificationDate = attributes[.modificationDate] as? Date {
        print("ファイルの最終更新日は\(modificationDate)です。")
    }

} catch {
    print("ファイルの属性の取得に失敗しました:\(error)")
}

このコードでは、FileManagerを使ってファイルの属性情報を取得するコードを表しています。

この例では、指定したファイルのサイズ、作成日、最終更新日を取得しています。

サンプルコードを実行すると、”サンプル.txt”というファイルの属性情報が表示されるはずです。

ただし、このコードを実行する前に、”サンプル.txt”という名前のファイルがドキュメントディレクトリに存在している必要があります。

○サンプルコード9:サブディレクトリ内のファイル操作

SwiftのFileManagerを使うと、サブディレクトリ内のファイル操作も簡単に行うことができます。

ここでは、サブディレクトリ内の全てのファイルをリストアップする方法と、特定のサブディレクトリにファイルを作成する方法を紹介します。

□サブディレクトリ内のファイルをリストアップする

このコードではFileManagerを使って、指定したディレクトリ内のサブディレクトリを含む全てのファイルのパスを取得するコードを表しています。

この例ではDocumentsディレクトリ内の全てのファイルとサブディレクトリのパスを取得しています。

import Foundation

let fileManager = FileManager.default
if let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
    do {
        let fileURLs = try fileManager.contentsOfDirectory(at: documentsURL, includingPropertiesForKeys: nil, options: [])
        for fileURL in fileURLs {
            print(fileURL.path)
        }
    } catch {
        print("エラー: \(error)")
    }
}

このコードを実行すると、Documentsディレクトリ内の全てのファイルとサブディレクトリのパスがコンソールに表示されます。

サブディレクトリがある場合、その中のファイルも表示されます。

□特定のサブディレクトリにファイルを作成する

このコードでは、指定したサブディレクトリに新しいファイルを作成するコードを表しています。

この例ではDocumentsディレクトリ内のsubdirという名前のサブディレクトリにsample.txtというファイルを作成しています。

import Foundation

let fileManager = FileManager.default
if let documentsURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
    let subDirURL = documentsURL.appendingPathComponent("subdir")
    let newFileURL = subDirURL.appendingPathComponent("sample.txt")
    let text = "サンプルテキスト"

    do {
        if !fileManager.fileExists(atPath: subDirURL.path) {
            try fileManager.createDirectory(at: subDirURL, withIntermediateDirectories: true, attributes: nil)
        }
        try text.write(to: newFileURL, atomically: true, encoding: .utf8)
        print("\(newFileURL.path) にファイルを保存しました。")
    } catch {
        print("エラー: \(error)")
    }
}

このコードを実行すると、Documentsディレクトリ内のsubdirディレクトリにsample.txtというファイルが作成され、指定したテキストが保存されます。

もしsubdirが存在しなければ、新しくサブディレクトリが作成された上でファイルが保存されます。

○サンプルコード10:大量のデータを効率的に扱う方法

大量のデータを取り扱う場合、データの読み書きやコピーに時間がかかることがあります。

FileManagerにはこれらのデータ操作を効率的に行うための方法が提供されています。

□ファイルを効率的にコピーする

このコードでは、FileManagerを使用して、大きなファイルを別の場所に効率的にコピーするコードを表しています。

この例では、sourceFileURLからdestinationFileURLへのファイルのコピーを行っています。

import Foundation

let fileManager = FileManager.default
let sourceFileURL = URL(fileURLWithPath: "path/to/source/file")
let destinationFileURL = URL(fileURLWithPath: "path/to/destination/file")

do {
    try fileManager.copyItem(at: sourceFileURL, to: destinationFileURL)
    print("ファイルを \(destinationFileURL.path) にコピーしました。")
} catch {
    print("エラー: \(error)")
}

このコードを実行すると、指定されたソースファイルが指定された宛先にコピーされます。

特に大きなファイルの場合、この方法は効率的にファイルのコピーを行うことができます。

□大きなファイルを分割して読み込む

大きなファイルを一度に読み込むと、メモリを大量に消費することがあります。

このような場合、ファイルを小さなチャンクに分割して読み込むことでメモリの使用量を節約することができます。

このコードでは、指定したサイズのチャンクに分割してファイルを読み込むコードを表しています。

この例では、fileURLからのファイルを1MBのチャンクに分割して読み込んでいます。

import Foundation

let fileURL = URL(fileURLWithPath: "path/to/large/file")
let chunkSize = 1_048_576 // 1MB

do {
    let fileData = try Data(contentsOf: fileURL)
    var chunks: [Data] = []
    var start = 0

    while start < fileData.count {
        let end = start + chunkSize
        let chunk = fileData.subdata(in: start..<min(end, fileData.count))
        chunks.append(chunk)
        start += chunkSize
    }

    print("ファイルを \(chunks.count) チャンクに分割しました。")
} catch {
    print("エラー: \(error)")
}

このコードを実行すると、指定したファイルが1MBのチャンクに分割され、それぞれのチャンクがchunks配列に追加されます。

この方法を使用することで、大きなファイルでもメモリを効率的に使用して読み込むことができます。

●FileManagerを使った際の注意点と対処法

FileManagerを使用する際には、いくつかの注意点と対処法が存在します。

これらの注意点を理解し、適切に対処することで、よりスムーズにFileManagerを活用することができます。

○エラーハンドリングの基本

Swiftでは、多くの操作がエラーを投げる可能性があります。

FileManagerを使用する際も、ファイルが存在しない、読み書きの権限がない、ディスク容量が不足しているなど、様々な原因でエラーが発生する可能性があります。

このコードでは、FileManagercontentsOfDirectory(atPath:)メソッドを使って、指定したディレクトリ内のファイル一覧を取得しようとしています。

この操作はエラーを投げる可能性があるため、do-catch文を使用してエラーハンドリングを行っています。

import Foundation

let fileManager = FileManager.default
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!

do {
    let files = try fileManager.contentsOfDirectory(atPath: documentsDirectory)
    for file in files {
        print(file)
    }
} catch {
    print("エラーが発生しました: \(error.localizedDescription)")
}

この例では、ドキュメントディレクトリ内のファイル一覧を取得し、コンソールに出力しています。

もしエラーが発生した場合は、エラーメッセージをコンソールに表示します。

実行結果として、正常にドキュメントディレクトリ内のファイル一覧がコンソールに出力されるでしょう。

もしエラーが発生した場合、そのエラー内容がコンソールに表示されます。

○パーミッションとセキュリティの考慮点

ファイルやディレクトリにアクセスする際には、パーミッションやセキュリティの考慮が必要です。

特にiOSやmacOSのようなサンドボックス環境では、アプリがアクセスできる範囲や権限が制限されているため、注意が必要です。

□アクセス権限の確認

アプリがファイルやディレクトリにアクセスする前に、必ずアクセス権限があるかどうかを確認することが重要です。

FileManagerisReadableFile(atPath:)isWritableFile(atPath:)を使用して、読み取りや書き込みの権限があるかどうかを確認できます。

□セキュリティの強化

ファイルやディレクトリの操作を行う際には、セキュリティを考慮し、データの暗号化やアクセス権の制限などの対策を講じることが推奨されます。

特に、個人情報や機密情報を扱う場合は、十分なセキュリティ対策を行うことが重要です。

●FileManagerのカスタマイズ方法

FileManagerはiOSやmacOSなどのSwiftベースのアプリケーションでファイルやディレクトリの操作を行う際に非常に役立つクラスです。

しかし、時として、デフォルトの動作だけでは要求される操作を実現するのが難しい場合があります。

そこで、今回はFileManagerのカスタマイズ方法について詳しく解説します。

○FileManagerのデフォルト動作の変更方法

FileManagerのデフォルトの動作を変更するためには、FileManagerのインスタンスを生成してから、そのプロパティやメソッドをカスタマイズすることで実現できます。

このコードではFileManagerのインスタンスを生成し、デフォルトの動作を変更する方法を示しています。

この例では、FileManagerのインスタンスを生成した後に、delegate プロパティを使用して、特定の操作の際の振る舞いをカスタマイズしています。

import Foundation

let fileManager = FileManager.default
fileManager.delegate = CustomFileManagerDelegate()

class CustomFileManagerDelegate: NSObject, FileManagerDelegate {
    func fileManager(_ fileManager: FileManager, shouldProceedAfterError error: Error, movingItemAt srcURL: URL, to dstURL: URL) -> Bool {
        // エラー発生時の動作をカスタマイズ
        // 例: ファイル移動時のエラーを無視して処理を続行する場合
        return true
    }
}

上記のサンプルでは、ファイル移動時にエラーが発生した場合でも、エラーを無視して処理を続行するカスタムのデリゲートを設定しています。

○拡張関数を利用した便利な機能追加

Swiftの強力な特徴の1つに、既存のクラスや構造体に拡張関数を追加することができる機能があります。

FileManagerも例外ではなく、特定の操作を簡略化するための拡張関数を追加することで、より柔軟なファイル操作を実現することが可能です。

このコードではFileManagerに新しいメソッドを追加して、特定のディレクトリ内のファイル一覧を取得する処理を簡素化しています。

この例では、allFiles(atPath:)という新しいメソッドを追加して、指定されたパスのディレクトリ内の全てのファイルの一覧を取得します。

import Foundation

extension FileManager {
    func allFiles(atPath path: String) -> [String]? {
        do {
            let files = try contentsOfDirectory(atPath: path)
            return files
        } catch {
            print("エラー: \(error)")
            return nil
        }
    }
}

// 使用例
let fileManager = FileManager.default
if let files = fileManager.allFiles(atPath: "/path/to/directory") {
    print(files)
}

上記のコードを実行すると、/path/to/directoryというディレクトリ内の全てのファイルの一覧が表示されます。

これにより、特定のディレクトリ内のファイル一覧を取得するためのコードを簡素化することができます。

まとめ

SwiftのFileManagerは、iOSやmacOSのアプリケーション開発においてファイルやディレクトリの操作を行うための重要なクラスです。

本記事では、FileManagerの基本的な使い方から応用例、そしてカスタマイズ方法までを解説しました。

初心者から中級者まで、FileManagerの使い方を学ぶ際の参考として、実用的な10のサンプルコードを提供しました。

これらのサンプルコードは、日常の開発作業での具体的な課題解決のヒントとして活用することができます。

特に、FileManagerのカスタマイズ方法では、デフォルトの動作を変更したり、拡張関数を利用して新しい機能を追加する方法を詳細に解説しました。

これにより、様々なニーズに応じてFileManagerをカスタマイズし、効率的なファイル操作を実現することが可能です。

FileManagerを使用する際は、エラーハンドリングやセキュリティの考慮点など、注意すべき点もあるため、十分な理解と注意を持って利用することが重要です。

SwiftのFileManagerの魔法を手に入れ、あなたのアプリケーション開発をさらにスムーズに進めるための知識として、本記事が役立つことを願っています。