ファイルの読み書き

ノート

 メモ帳やToDoリストでは、内容をiPhoneやiPadへ記憶しておく必要があります。たいていのアプリで情報の保存は重要になります。ここでは、文字の記憶と読み出しを行う方法について解説します。

iOSにおけるフォルダ構造

 iOSにおけるフォルダはOS XやWindowsと比べ少し特殊です。はじめにiOSにおけるフォルダについて解説します。iOSにはアプリごとに以下のようなファイルが用意されています。

  1. ホーム/Documents/
  2. ホーム/Library/Preferences/
  3. ホーム/Library/Caches/
  4. ホーム/tmp/

Documentsにはアプリで使用するデータを保存します。Preferencesにはアプリの環境設定ファイルを保存します。Cachesやtmpはアプリで一時的に使用するファイルを保存します。大きなデータを扱う際に、メモリではなくファイルに保存して使用する際にこれらのフォルダにファイルを保存します。Cachesはアプリ起動中にファイルが削除されることがあり、tmpは起動中に削除されることはありません。

テキストの読み書き

 以下のようなプログラムを作ります。まず、テキストフィールドに文字を入力し、書き込みボタンを押したらDocumentsにtest.txtというファイルを書き込みます。そして、読み込みボタンを押したら記憶したtest.txtから文字を読み取ります。

プロジェクトの作成

 Xcodeを起動して「Create a new Xcode project」を選択します。

createnewproject

そして、iOSのSingle View Applicationを選択します。

singleview

プロジェクト名と言語を使用します。ここではSwiftとします。

プロジェクトの設定

ユーザーインターフェースの作成

 文字入力用のText Fieldと書き込み・読み込み用のButtonを2つ、そして、Labelを配置します。

result

Constraintsで、配置を固定します。4つとも上、左右の隙間を固定します。

constrains

その後、2画面にして以下のようにプロパティとメソッドを右クリックのドラッグ&ドロップでViewController.swiftへ導入します。

  1. 書き込み用textFieldのプロパティ:input
  2. 表示用ラベルのプロパティ:output
  3. 書き込みボタンのアクション:write
  4. 読み込みボタンのアクション:read

コードを書く

 以下のようにボタンを押した際のコードを書きます。ファイルはViewController.swiftです。

import UIKit

class ViewController: UIViewController {

    @IBOutlet var input: UITextField!
    @IBOutlet var output: UILabel!
    @IBAction func write(sender: UIButton) {
        let data=input.text
        if let byte_data:NSData=data.dataUsingEncoding(NSUTF8StringEncoding){
            var path=NSHomeDirectory().stringByAppendingPathComponent("Documents")
            path=path.stringByAppendingPathComponent("test.txt")
            byte_data.writeToFile(path, atomically: true)

        }

    }
    @IBAction func read(sender: UIButton) {
        var path=NSHomeDirectory().stringByAppendingPathComponent("Documents")
        path=path.stringByAppendingPathComponent("test.txt")
        if let data:NSData=NSData(contentsOfFile: path,options: .DataReadingMappedIfSafe, error:nil){
            output.text=NSString(data: data,encoding: NSUTF8StringEncoding)
        }

    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

書き込み

    @IBAction func write(sender: UIButton) {
        let data=input.text
        if let byte_data:NSData=data.dataUsingEncoding(NSUTF8StringEncoding){
            var path=NSHomeDirectory().stringByAppendingPathComponent("Documents")
            path=path.stringByAppendingPathComponent("test.txt")
            byte_data.writeToFile(path, atomically: true)

        }

    }

書き込みでは、テキストフィールドの文字列をバイト配列に変換しています。バイト配列への変換は以下の命令をつかいます。

NSDataへの変換

func dataUsingEncoding(encoding: UInt) -> NSData?

NSStringクラスのメソッド。文字列をNSDataへ変換する。入力値は以下のとおり。

入力値 意味
NSUTF8StringEncoding UTF-8
NSShiftJISStringEncoding Shift-JIS
NSJapaneseEUCStringEncoding EUC-JP

その後、バイト配列をファイルに書き込みます。ファイルへの書き込みには以下の命令を使用します。

NSDataのファイル書き込み

func writeToFile(path: String, atomically: Bool) -> Bool

NSDataクラスのメソッド。ファイルへNSDataを書き込む。pathにパスを指定。atomicallyで安全に書き込むかどうかを指定する。成功するとTrueを返す。

 パスの位置はNSHomeDirectoryを使用します。

ホームのパスを取得

func NSHomeDirectory() -> String!

ホームのパスを返す

 今回はHome下のDocumentsにtest.txtを保存するので、Home/Documents/test.txtとパスをする必要があります。そのために

パスの編集

func stringByAppendingPathComponents(aString: String) -> String

セパレーション「/」つきでファイル名やフォルダ名を追加する。aStringが追加するファイル名かフォルダ名。戻り値は追加したパスになる。

を使用してパスを設定しています。

読み込み

    @IBAction func read(sender: UIButton) {
        var path=NSHomeDirectory().stringByAppendingPathComponent("Documents")
        path=path.stringByAppendingPathComponent("test.txt")
        if let data:NSData=NSData(contentsOfFile: path,options: .DataReadingMappedIfSafe, error:nil){
            output.text=NSString(data: data,encoding: NSUTF8StringEncoding)
        }

    }

 読み込みでは、まず指定したパスからバイト配列を読み込みます。命令は以下のものを使用します。

ファイルの読み込み

 NSData(path: String, mask: NSDataReadingOptions, errorPtr: NSErrorPointer)

ファイルからNSDataを読み込む。pathは読み込みファイルのパス。errorPtrはエラー情報。maskにオプションを設定する。オプションは以下のとおり。

意味
DataReadingMappedIfSafe 可能なら、仮想メモリにマッピングする
DataReadingMappedAlways 仮想メモリにマッピングする
DataReadingUncached 仮想メモリにマッピングしない

読み込んだバイト配列を文字列へ変換して表示させます。この変換には以下の命令を使用します。

文字列への変換

 NSString(bytes: UnsafePointer<Void>, encoding: UInt)

NSDataからStringへ変換。bytesにNSData、encodingにdataUsingEncodingの表に示すエンコーディングを指定。

実行結果

 プログラムを実行すると以下のようになります。文字を入力して書き込みを押すとファイルに記憶されます。

 file

そして、読み込みを押すと記憶した文字列を読み込むことができます。

 read

プログラムを再起動してもファイルは残るので、前回記憶した文字列を読み出せます。

著者:安井 真人(やすい まさと)