swift - FileManager.contentsEqual 在比较复制的文件时返回 false

标签 swift nsfilemanager

我需要将 SQLite 文件从我的包的资源中预加载到应用程序支持目录中。我想确保那里有正确的文件,而不是 Core Data 默认放置在那里的空文件。为此,我使用了 FileManager.default.contentsEqual;然而,这总是返回 false

我尝试在 playground 上进行测试,但那里的副本正在创建别名文件,仍然导致 false 比较。

在应用程序中,文件会以相同的名称和大小进行复制。日期不同:副本具有当前日期/时间而不是原件的时间戳。不过,我认为使用 contentsEqual 并不重要。

更新: diff 在命令行显示文件相同...

我错过了什么?


这是来自 playground 的代码,它与我的应用程序代码几乎相同:

// get the URL for the application support directory
let appSupportDir: URL = try!
 FileManager.default.url(for: FileManager.SearchPathDirectory.applicationSupportDirectory,
                         in: FileManager.SearchPathDomainMask.userDomainMask,
                         appropriateFor: nil, create: true)

// get the source URLs for the preload files
let sqliteFileBundleURL: URL = Bundle.main.url(forResource: "My_DB", withExtension: "sqlite")!
let sqliteShmFileBundleURL: URL = Bundle.main.url(forResource: "My_DB", withExtension: "sqlite-shm")!
let sqliteWalFileBundleURL: URL = Bundle.main.url(forResource: "My_DB", withExtension: "sqlite-wal")!

// create target URLs for copy to application support directory
let sqliteFileAppSptURL: URL = appSupportDir.appendingPathComponent("My_DB.sqlite")
let sqliteShmFileAppSptURL: URL = appSupportDir.appendingPathComponent("My_DB.sqlite-shm")
let sqliteWalFileAppSptURL: URL = appSupportDir.appendingPathComponent("My_DB.sqlite-wal")

// remove the files if they already exist at the target (for test - app doesn't do this)
do {
    let filesFound: [URL] = try FileManager.default.contentsOfDirectory(at: appSupportDir,
                                                                    includingPropertiesForKeys: nil,
                                                                    options: .skipsHiddenFiles)
    if !filesFound.isEmpty {
        for fileURL in filesFound {
            try FileManager.default.removeItem(at: fileURL)
        }
        print("Removed \(filesFound.count) files without error.")
    }
}
catch {
    print("Error:\n\(error)")
}

// copy the files to the application support directory
do {
    try FileManager.default.copyItem(at: sqliteFileBundleURL, to: sqliteFileAppSptURL)
    try FileManager.default.copyItem(at: sqliteShmFileBundleURL, to: sqliteShmFileAppSptURL)
    try FileManager.default.copyItem(at: sqliteWalFileBundleURL, to: sqliteWalFileAppSptURL)
}
catch {
    print("Error: \(error)")
}

// compare the copied target files to their source using contentsEqual
let sqliteFileCopied: Bool =
 FileManager.default.contentsEqual(atPath: sqliteFileBundleURL.absoluteString, andPath: sqliteFileAppSptURL.absoluteString)
let sqliteShmFileCopied: Bool =
 FileManager.default.contentsEqual(atPath: sqliteShmFileBundleURL.absoluteString, andPath: sqliteShmFileAppSptURL.absoluteString)
let sqliteWalFileCopied: Bool =
 FileManager.default.contentsEqual(atPath: sqliteWalFileBundleURL.absoluteString, andPath: sqliteWalFileAppSptURL.absoluteString)

最佳答案

啊哈!使用 FileManager 时,应该使用 path 而不是 absoluteStringURL 转换为 String :

// compare the copied target files to their source using contentsEqual
let sqliteFileCopied: Bool =
 FileManager.default.contentsEqual(atPath: sqliteFileBundleURL.path, andPath: sqliteFileAppSptURL.path)
let sqliteShmFileCopied: Bool =
 FileManager.default.contentsEqual(atPath: sqliteShmFileBundleURL.path, andPath: sqliteShmFileAppSptURL.path)
let sqliteWalFileCopied: Bool =
 FileManager.default.contentsEqual(atPath: sqliteWalFileBundleURL.path, andPath: sqliteWalFileAppSptURL.path)

两者的区别在于path生成的是文件系统类型的路径:

/var/folders/kb/y2d_vrl133d1b04_5kc3kw880000gn/T/com.apple.dt.Xcode.pg/resources/238FF955-236A-42FC-B6EA-9A74FC52F235/My_DB.sqlite

absoluteString 生成浏览器友好的路径:

file:///var/folders/kb/y2d_vrl133d1b04_5kc3kw880000gn/T/com.apple.dt.Xcode.pg/resources/238FF955-236A-42FC-B6EA-9A74FC52F235/My_DB.sqlite

注意:path 也可以在 playground 中使用别名文件。

关于swift - FileManager.contentsEqual 在比较复制的文件时返回 false,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41132067/

相关文章:

ios - 如何比较 "file://localhost/var/mobile/..."与 "file:///var/mobile/..."的 URL

Swift - 从 Firebase DB 中提取的数据按最近位置排序

ios - 从另一个 ViewController 调用函数发现错误

ios - Swift 中的线程队列

ios - Xcode 获取一致的文档目录路径

objective-c - 在 NSFileManager 中将文件从一个位置复制到另一个位置时出错

ios - 重命名文件而不输入文件扩展名

c++ - 在 Swift 项目中使用 C++ 文件

objective-c - swift 代表。

objective-c - NSFileManager setUbiquitous:是,我的文件陷入了困境!为什么?