0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Swift] 既に存在するファイルに対して上書きコピーできない件

Last updated at Posted at 2023-11-15

この記事で分かること

  • 書き込む (write する) 際は既に存在するファイルに対して、上書きして書き込むことができる
  • 既に存在するファイルに対して上書きコピーしようとすると失敗する
    • そのため、コピーの前には、ファイルが存在するかチェックしてから、コピー先のファイルを削除してあげるとよさそう

書き込み ( write ) の場合

ファイルに書き込む方法

まず、基本的な挙動として、ファイルを書き込む方法は以下の通りです。

import Foundation

// 適当な文字列を用意
let text = "\(Date())"
print("text: \(text)") // text: 2021-12-26 00:48:11 +0000

// 保存先のディレクトリを用意
let dir = FileManager.default.urls(for: .documentDirectory,in: .userDomainMask).first!
print("dir: \(dir)") // dir: file:///Users/xxxxxxx/Documents/

// 適当なファイルを用意
let fileUrl1: URL = dir.appendingPathComponent("test_1.txt")
print("fileUrl1: \(fileUrl1)") // fileUrl1: file:///Users/xxxxxxx/Documents/test_1.txt

do {
    // ファイルにテキストに書き込む
    try text.write(to: fileUrl1, atomically: false, encoding: .utf8)
} catch {
    print("Error: \(error)")
}

これで、fileUrl1text を書き込むことができます。

同じファイルに2回書き込んでも失敗しない

write については同じファイルに2回書き込んでも失敗することはありません。

do {
    // ファイルにテキストに書き込む
    try text.write(to: fileUrl1, atomically: false, encoding: .utf8)
    
    // 2回同じファイルに対してに書き込んでもエラーにならない
    try text.write(to: fileUrl1, atomically: false, encoding: .utf8)
} catch {
    print("Error: \(error)")
}

そして、後半に write した text の内容がファイルに上書きされます。

コピー ( copyItem ) の場合

コピーする方法

まず、基本的な挙動として、ファイルをコピーする方法は以下の通りです。

// 適当なファイルをもうひとつ用意
let fileUrl2: URL = dir.appendingPathComponent("test_2.txt")
print("fileUrl2: \(fileUrl2)") // fileUrl2: file:///Users/xxxxxxx/Documents/test_2.txt

do {
    try FileManager.default.copyItem(at: fileUrl1, to: fileUrl2) 
} catch {
    print("Error: \(error)")
}

これで、fileUrl1 の内容が fileUrl2 に内容がコピーされて、fileUrl2 にファイルが新たに作成されます。

既にファイルが存在するとコピーに失敗する

copyItem については、既にファイルが存在場合はコピーに失敗します。

do {
    // 既にファイルが存在するとコピーに失敗する
    try FileManager.default.copyItem(at: fileUrl1, to: fileUrl2)
    try FileManager.default.copyItem(at: fileUrl1, to: fileUrl2)
} catch {
    print("Error: \(error)") // Error: Error Domain=NSCocoaErrorDomain Code=516 "“test_1.txt” couldn’t be copied to “Documents” because an item with the same name already exists."
}

コピーの前にはチェック&削除が必要

そのため、コピーの前にはチェック&削除が必要になります。

do {
    // コピーの前にはチェック&削除が必要
    if FileManager.default.fileExists(atPath: fileUrl2.path) {
        // すでに fileUrl2 が存在する場合はファイルを削除する
        try FileManager.default.removeItem(at: fileUrl2)
    }
    try FileManager.default.copyItem(at: fileUrl1, to: fileUrl2) // fileUrl2 が存在しないこと保証されているのでエラーは発生しない
} catch {
    print("Error: \(error)")
}

これで安全にコピーできます。

結論

  • 書き込む (write する) 際は既に存在するファイルに対して、上書きして書き込むことができる
  • 既に存在するファイルに対して上書きコピーしようとすると失敗する
    • そのため、コピーの前には、ファイルが存在するかチェックしてから、コピー先のファイルを削除してあげるとよさそう
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?