有没有办法使用内存映射文件访问从文件创建CFData对象?

时间:2012-09-26 23:07:53

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

我被限制在特定应用中使用CoreFoundation,并且无法访问NSData

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

是否可以使用CFData执行此操作?我可以找到直接从文件中实际创建CFData对象的唯一函数是CFURLCreateDataAndPropertiesFromResource()函数,它没有任何设置内存映射标志的选项。

是否有使用内存映射读取从文件加载CFData对象的低级方法?我是否必须下载到mmap或其他什么?

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

这不仅仅是一个评论而是一个答案,但是它太长了,不适合评论,所以......

通常,当您不知道如何从Cocoa / Foundation执行某些操作时,通常值得研究如何实现GNUstep等效项。当然GNUstep没有实现100%的最新版本的Foundation,它直接写在POSIX而不是CoreFoundation之上,所以它并不总是有用......但通常都是。

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

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

所以,这是一个很好的线索,你想要完全按照Kevin Ballard的建议实现这一点。