How can I read a NSData

NSData *theInformationData = //some information data;
NSData *encryptedData = //some encrypted data;
NSMutableData *theMainFile = [NSMutableData dataWithBytes:&theInformationData length:sizeof(theInformationData)];
[theMainFile appendData:encryptedData];


Now if write theMainFile to a file and want to read it from some other code. How can I exctract theInformationData without knowing the length of it? Is the length of theInformationData store in someway in theMainFile?


NSData *theExtractedInformation = [NSData data];
[theMainFile getBytes:&theExtractedInformation length:<#(NSUInteger)#>];



It think I should use this function getBytes: length: but I dont know the length?


Can someone point me in a direction? I hope I dont need to save the length of the theInformationData somewhere seperated from the file. This would seem inconvenient.


Thanks in advance.

Replies

When you read data from a file the length, using something like

+dataWithContentsOfURL:options:error:
, the length of the data is set to the length of the file. You can get that from the data using the
length
property.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

If I understand your question correctly, then no. You will not be able to retrieve just the length of theInformationData without the encryptedData that you appened onto the end of it. You are writing structured data. You have to encode the definition of the strucure somewhere if the length of theInformationData is not fixed in the code. Even if it is fixed in the code, that would be a bad idea.


One option would be to include a fixed header in theInformationData that defines how long it is. Then, you can read just that fixed portion first. Once you know how big the rest is, you can read that. Then you would know that encryptedData would follow.


Another option would be to define some overall structure to this file and embed the lengths of both sections of data at the beginning of the file. Or you could use some structured file format like XML and encode the data within it.

This line:


NSMutableData *theMainFile = [NSMutableData dataWithBytes:&theInformationData length:sizeof(theInformationData)];


is very wrong. That does not add the data contained by the NSData object pointed to by theInformationData to theMainFile. It puts the value of the pointer into theMainFile. That is, it's putting the address of an object into theMainFile, not the contents of that object. And the address is not meaningful in any other process, even future invocations of your own program. (It's not even reliably meaningful later in the same process since the data object may be deallocated.)

Yes! Thanks for catching that.


Also, the getBytes: length: is equally wrong. Both of these constructs are designed for C structures. They could be correctly written like this:


typedef struct InformationData
  {
  short someData;
  ...
  uint64_t someOtherData;
  }
InformationData;

InformationData theInformationData;

NSMutableData * theMainFile = [NSMutableData dataWithBytes: & theInformationData length: sizeof(theInformationData)];


Then, you could read it like so:


InformationData theExtractedData;

[theMainFile getBytes: & theExtractedInformation length: sizeof(theExtractedData)];

>Can someone point me in a direction? I hope I dont need to save the length of the theInformationData somewhere seperated from the file. This would seem inconvenient.


You are combining two NSData objects using appendData. Combine three - the first being the length of the second. Then to decombine, first extract that length then extract the second then extract the third.