Reputation: 46020
I am restricted to using CoreFoundation in a particular app, and don't have access to NSData
.
I need to access data from a file using memory mapping because the file could be quite large. With NSData
, I can achieve this using the +dataWithContentsOfURL:options:error:
method, passing in the NSDataReadingMappedAlways
option.
Is it possible to do this with CFData
? The only function I can find to actually create a CFData
object directly from a file is the CFURLCreateDataAndPropertiesFromResource()
function, which does not have any option to set the memory mapping flag.
Is there a lower-level way to load a CFData
object from a file using memory-mapped reads? Do I have to drop down to mmap
or something?
Upvotes: 3
Views: 2359
Reputation: 365717
This is more of a comment than an answer, but it's too long to fit in a comment, so…
In general, when you don't know how to do something from Cocoa/Foundation, it's often worth looking at how the GNUstep equivalent is implemented. Of course GNUstep doesn't implement 100% of the latest version of Foundation, and it's written directly on top of POSIX rather than CoreFoundation, so it isn't always helpful… but often it is.
In NSData.m, there's no +dataWithContentsOfURL:options:error:
, but there is a +dataWithContentsOfMappedFile:
(and of course -initWithContentsOfMappedFile:
) method, and the implementation of the NSDataMappedFile
class that it depends on.
Ultimately, the NSDataMappedFile
is a pretty simple wrapper around an mmap
, and the NSData
methods just create an NSDataMappedFile
and call its -initWithContentsOfMappedFile:
. The only real complexity is the fallback code (which makes sure to fake the mmap and just call [NSData initWithContentsOfFile:]
)—code which you explicitly don't want.
So, that's a good clue that you want to implement this exactly the way Kevin Ballard suggested.
Upvotes: 3
Reputation: 185671
You can create a CFData()
from a byte buffer and a count. Given this, you should just be able to mmap()
the file in question, and then pass the mapped byte buffer over to CFDataCreateWithBytesNoCopy()
. The only real complication is you'll need to use a CFAllocatorRef
that knows how to munmap()
as the bytesDeallocator
.
Upvotes: 5