【问题标题】:Is there a way to create a CFData object from a file using memory-mapped file access?有没有办法使用内存映射文件访问从文件创建 CFData 对象?
【发布时间】:2012-09-26 23:07:53
【问题描述】:

我只能在特定应用中使用 CoreFoundation,并且无权访问 NSData

我需要使用内存映射访问文件中的数据,因为该文件可能非常大。使用NSData,我可以使用+dataWithContentsOfURL:options:error: 方法实现这一点,传入NSDataReadingMappedAlways 选项。

可以用CFData 做到这一点吗?我能找到的唯一可以直接从文件中创建CFData 对象的函数是CFURLCreateDataAndPropertiesFromResource() 函数,它没有任何设置内存映射标志的选项。

有没有使用内存映射读取从文件中加载CFData 对象的低级方法?我必须下拉到mmap 吗?

【问题讨论】:

  • 作为一个快速的旁注:如果你只想避免缓存,你应该使用 NSDataReadingUncached,而不是 NSDataReadingMappedAlways。除非您实际上需要要映射的数据,即使不安全或速度较慢(想想 NFS),为什么要要求它呢?但是,更重要的是,NSDataReadingMappedAlways 只是一个“如果可能,映射文件的提示”——如果它不能被映射,它将被正常读取,并且可能存储在缓存中。
  • 有趣,非常感谢您的澄清。

标签: objective-c macos cocoa-touch cocoa core-foundation


【解决方案1】:

您可以从字节缓冲区和计数创建CFData()。鉴于此,您应该能够mmap() 有问题的文件,然后将映射的字节缓冲区传递给CFDataCreateWithBytesNoCopy()。唯一真正的复杂性是您需要使用知道如何将munmap() 用作bytesDeallocatorCFAllocatorRef

【讨论】:

  • 谢谢,我认为可能是这样。没有更高级别的方法可以做到这一点,但我可以使用它,这有点烦人。
【解决方案2】:

这更像是一个评论而不是一个答案,但它太长了,无法放入评论中,所以……

一般来说,当您不知道如何从 Cocoa/Foundation 做某事时,通常值得看看 GNUstep 等效项是如何实现的。当然 GNUstep 并没有 100% 实现 Foundation 的最新版本,而且它是直接在 POSIX 而不是 CoreFoundation 之上编写的,所以它并不总是有帮助……但通常是有帮助的。

NSData.m 中,没有+dataWithContentsOfURL:options:error:,但有一个+dataWithContentsOfMappedFile:(当然还有-initWithContentsOfMappedFile:)方法,以及它所依赖的NSDataMappedFile 类的实现。

最终,NSDataMappedFile 是一个非常简单的 mmap 包装器,NSData 方法只是创建一个NSDataMappedFile 并调用它的-initWithContentsOfMappedFile:。唯一真正复杂的是后备代码(确保伪造 mmap 并调用 [NSData initWithContentsOfFile:])——这是您明确不想要的代码。

所以,这是一个很好的线索,您希望完全按照 Kevin Ballard 的建议来实现它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    相关资源
    最近更新 更多