我试图了解Core Data属性的Allows External Storage属性的行为,并查看它是否可以免于手动将文件存储在文件系统中的麻烦。我想看看在处理非常大的文件时它将如何执行。为此,我创建了一个虚拟项目,并使用Core Data存储了一个大文件(2 GB)。然后,我在获取和处理数据时监视了内存使用情况,令我惊讶的是,它没有超过48 MB!这是为什么?它会分块获取数据吗?如果是这样,怎么办? Data结构是否具有允许Core Data做到这一点的API?

我所做的更多详细信息:

  • 创建了仅具有两个属性File(字符串)和fileName(数据)的实体data

  • ios - 核心数据:大文件“允许外部存储”性能-LMLPHP
  • 检查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)")
    }
    
  • File类的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/

    10-10 21:20
    查看更多