我试图了解Core Data属性的Allows External Storage
属性的行为,并查看它是否可以免于手动将文件存储在文件系统中的麻烦。我想看看在处理非常大的文件时它将如何执行。为此,我创建了一个虚拟项目,并使用Core Data存储了一个大文件(2 GB)。然后,我在获取和处理数据时监视了内存使用情况,令我惊讶的是,它没有超过48 MB!这是为什么?它会分块获取数据吗?如果是这样,怎么办? Data
结构是否具有允许Core Data做到这一点的API?
我所做的更多详细信息:
File
(字符串)和fileName
(数据)的实体data
。 Allows External Storage
属性的data
属性。 File
实体中存储了2 GB的文件。我将这段代码放在viewDidLoad
方法中。do {
// Store file
let fileURL = Bundle.main.url(forResource: "RawData/LargeFile", withExtension: nil)!
let file = File(context: AppDelegate.viewContext)
file.name = fileName
file.data = try Data(contentsOf: fileURL)
try AppDelegate.viewContext.save()
} catch {
print(error.localizedDescription)
}
viewDidLoad
中的新代码重新启动该应用程序,以获取并处理大文件的数据。let fileData = File.files(named: name).first!.data!
DispatchQueue.global(qos: .userInteractive).async {
let result = self.process(data: fileData)
print("The result: \(result)")
}
files
静态方法返回File实体中的所有文件。 这是处理方法,该方法逐字节循环遍历数据,进行读取和XOR运算,然后返回结果。确实可以是任何方法,这里重要的是读取数据的所有字节。
private func process(data: Data) -> UInt8 {
print("Processsing \(data.count) bytes")
var accumulator: UInt8 = 0
for byte in data {
accumulator ^= byte
}
return accumulator
}
我非常确定它与Core Data无关,而不与
Data
有关,因为从磁盘加载data
(Data(contentsOf: URL)
)时执行相同的步骤将导致3 GB以上的内存使用(此外,为什么还要增加1 GB?)。最后,是否有任何理由不使用
Allows External Storage
功能,而是在文件系统中手动存储文件?我知道这个问题已经讨论了很多。但是,尽管我的小实验表明Core Data的性能很好,但我已阅读的大多数建议使用手动方式的建议都提到了Core Data的性能问题。任何帮助,将不胜感激!
最佳答案
关系数据库通常不好,无法存储和检索大量数据。任何大于兆字节的内容都不应存储在数据库中。核心数据使问题更加严重。如果直接访问数据库,则只能获取特定的列,但是由于核心数据将行转换为对象,而将列转换为属性,因此您无法控制获取的内容。当您将属性设置为Allows External Storage
时,Core-data会将大量数据存储在文件系统中,并且仅在您访问该属性时才加载它。这在很多情况下都非常有用,因为它很容易并且可以大大提高性能。
问题在于,访问此类属性可能会给加载大文件带来意想不到的巨大开销,而这仅仅是从访问属性时尚不清楚的。相反,如果您存储文件名并明确地具有从磁盘加载文件的第二步,那将是在加载数据时。另外,如果可以从Internet恢复此数据(例如,它们是从imageURL下载的图像),则最好在核心数据之外进行管理,因为您可以管理在核心数据中很难做到的缓存。
关于ios - 核心数据:大文件“允许外部存储”性能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57372449/