ファイル追記書き込み(Swift)
Oct 10, 2017 · iosswift3
Swiftっぽくファイルの書き込みをする方法
iOSでファイルへの追記書き込みをしたい場合、
FileHandle
でファイルを開くseekToEndOfFile
でファイルポインタをファイルの最後に移動させるwrite
で書き込む
というのが、ググるとよく出てくる方法である
上記の方法自体は間違っていないが、ファイルへの書き込みが失敗した(write
を実行したらエラーが発生した)場合のエラーが戻り値ではなく、例外で投げられてしまうという問題がある
しかも、この時に投げられる例外はSwiftの例外ではキャッチできないタイプとなっている
もちろん、こういった方法を使えばキャッチできなくはないが、正直、面倒である
という訳で、いろいろ探してたどり着いたのがOutputStream
を使う方法
ソース
メソッドにすると以下のような感じ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func write(url: URL, text: String) -> Bool { | |
guard let stream = OutputStream(url: url, append: true) else { | |
return false | |
} | |
stream.open() | |
defer { | |
stream.close() | |
} | |
guard let data = text.data(using: .utf8) else { return false } | |
let result = data.withUnsafeBytes { | |
stream.write($0, maxLength: data.count) | |
} | |
return (result > 0) | |
} |
解説
2行目で書き込み用のストリームを作成する時に、append
で追記書き込みを指定している。
なお、ここをfalse
にすると通常のファイル書き込みに、true
にすると追記になる
7~9行目ではdefer
を使ってclose処理を予約している。
これにより以降の処理でこのメソッドを抜ける(例えば11行目でreturn false
になった)時に、自動的にdefer
の中のstream.close()
が実行される
defer
は書かれた直後から有効になるので、open
の直後に書いておくのがポイント。
これにより、ファイルのクローズ処理漏れがなくなる
13~15行目で書き込み処理。
write
はポインタでデータを受け取り結果を返すのでこういう書き方になる
本当はちゃんとSwiftで例外を受け取れる様になれば一番良いのだけど・・・
開発環境
- Xcode 8.3.3
- iOS 10.3