我需要将我的bundle资源中的SQLite文件预加载到应用程序支持目录中。我想确保存在正确的文件与默认情况下Core Data放在那里的空文件。为此,我使用FileManager.default.contentsEqual
;但是,这总是返回false
。
我尝试使用游乐场进行测试,但副本中创建的是别名文件,仍然会进行false
比较。
在应用程序中,文件会以相同的名称和大小进行复制。日期不同:副本具有当前日期/时间而不是原始时间戳。但是,使用contentsEqual
,我认为不重要。
更新: diff
在命令行显示文件是相同的......
我错过了什么?
这里是操场上的代码,与我的应用代码几乎相同:
// 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)
答案 0 :(得分:1)
啊哈!使用FileManager
时,应使用path
而不是absoluteString
将URL
转换为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
也可以在操场上使用别名文件。