tags:

views:

303

answers:

1

I have an NSData that I would like to read as an NSInputStream. This way I can have a consistent API for processing both files and in-memory data. As part of the processing, I would like to make sure that the stream begins with some set of bytes (if it doesn't, I need to process it differently). I'd like to avoid reading a whole file into memory if it's of the wrong type.

So I'm looking for either a way to rewind the stream, or a way to "peek" at the upcoming bytes without moving the read pointer. If this is an NSInputStream created with URL, I can use setProperty:forKey: on NSStreamFileCurrentOffsetKey, but bizarrely this does not work on an NSInputStream created from an NSData (even though you would presume this would have been even easier to implement than the file version). I can't close and reopen the steam to reset the input pointer either (this is explicitly not allowed by NSStream).

I can rework this problem using an NSData-only interface and -initWithContentsOfMappedFile, but I'd rather stay with the NSStream approach if I can.

A: 

I think I don't understand something here. An NSInputStream can take data from three places: a socket, an NSData object, or a file. You haven't said that you want to use a socket, which leaves the other two as your data sources. Also, docs for NSStream say that only file-based streams are seekable. (NSStream, overview, 3rd paragraph)

Given that, I'd think that an NSData object would be a better choice. An NSData object will handle both files and bytes (which I think is what you mean by data in memory).

But you consider that and say that you'd prefer to stick with streams. Is there some other consideration here?

(Edit) Sorry, I should have made this a real answer. My answer for the issue you've described is that using NSData really is the right thing to do.

If you prefer a different answer, then please give more details.

Do you have a link to the reference that only file-based streams are seekable? I hadn't been able to find that so far. This seems crazy, since it's easier to seek an NSData than a file (not saying it's not true; just that it's crazy). We've rewritten using a memory-mapped NSData, but it's not clear yet whether this gives the performance we'd like on both Mac and iPhone (we're currently testing how memory mapped NSData performs on iPhone). The key point is "I'd like to avoid reading a whole file into memory if it's of the wrong type."
Rob Napier
Hi Rob, Reference is in the parenthetical remark above, albeit in shorthand. Apple's reference document for NSStream, Overview section, third paragraph. Which says, "By default, NSStream instances that are not file-based are non-seekable, one-way streams (although custom seekable subclasses are possible). Once the data has been provided or consumed, the data cannot be retrieved from the stream."I agree that this sounds crazy. But, that's what the doc says.