Binary Data Programming Guide

Contents

Data Objects //数据封装类

Working With Binary Data //创建和使用样例

Working With Mutable Binary Data //修改NSMutableData

原文:Binary Data Programming Guide


Data Objects

如果一个函数参数为 NSData*,可以用 CFDataRef* 传进去,但是反过来的话只能用 NSMutableData*

参见 NSData Class Reference, NSData理论上可以存储1EB = 1024PB 数据

The size of the data is subject to a theoretical limit of about 8 ExaBytes (in practice, the limit should not be a factor).

当 NSData 对象保存的数据超过一个内存页大小, 会启用虚拟内存机制.

不管一个对象在内存是怎样被分配的, NSData 都可以把它封装起来. 但是它不负责被保存对象的任何信息,包括对象的类

特别要注意的是, NSData 不会对封装起来的数据做字节序(big/little-endian)的转换处理. 如果你需要这个功能,请使用 NSValue

NSData 提供一种独立于系统的内存管理机制, 在使用 copy 功能的时候并不会在内存或虚拟内存里面真正的分配内存. 而是在你尝试修改这份 copy 的时候才分配内存


Working With Binary Data

由于框架类的划分, Data 对象并不算是 NSData/NSMutableData 对象实例,而是NSData/NSMutableData 的子类的实例

虽然 Data 实例的类私有,但是 inerface 还有有挺多函数可以供我们用的


Creating Data Objects From Raw Bytes

使用 raw bytes 创建 Data 对象的时候, 创建出来的 Data 对象直接复制了一份传入的 raw bytes. 这个被复制过来的 raw bytes 所占用的内存会在 Data 对象被释放的时候释放. 但是作为参数参入的 raw bytes 其自身是不会自动被释放的哟. 


你也可以直接使用带 NoCopy 的方法实例化 Data 对象, 这个时候会直接使用 strong 属性占有(own)传入raw bytes, 不再另外创建副本. 也会在释放 Data 实例的时候将其内存空间释放. 这个时候, 传入的 raw bytes 必须是使用 malloc 方法创建的


如果希望使用带有 NoCopy 的方法实例化 Data 对象时, Data 对象的创建和释放不影响原 raw bytes, 可以使用

dataWithBytesNoCopy:length:freeWhenDone:

把 freeWhenDone 设置为 NO


Creating Data Objects From Files or URLs

NSString *thePath = @"/Users/adolsai/Public/Demo/readme.txt";
NSData *myData = [NSData dataWithContentsOfFile:thePath];
NSLog(@"%s",[myData bytes]);
//OUTPUT: 2015-06-12 17:29:37.788 XYZPersonTest[1341:106416] 123456(文件内容)


Accessing and Comparing Bytes

两个最基本的属性:bytes,length

复制 Data:getBytes:length:

unsigned char aBuffer[20];
NSString *myString = @"Test string.";
const char *utfString = [myString UTF8String];

NSData *myData = [NSData dataWithBytes:utfString length:strlen(utfString)];
[myData getBytes:aBuffer length:20];

NSLog(@"%s",aBuffer);
// %s 8bit unsigned character
// %S 16bit unicode character
//OUTPUT: 2015-06-12 17:35:51.536 XYZPersonTest[1363:108661] Test string.


截取: subDataWithRange:

比较: isEqualToData:

NSString *myString = @"ABCDEFG";
const char *utfString = [myString UTF8String];
NSRange range = {2,4};
NSData *data1,*data2;

data1 = [NSData dataWithBytes:utfString length:strlen(utfString)];
data2 = [data1 subdataWithRange:range];

NSLog(@"%s",[data2 bytes]);
//OUTPUT: 2015-06-12 17:40:59.269 XYZPersonTest[1386:110872] CDEF

NSLog(@"%d",[data1 isEqualToData:data2]);
//OUTPUT: 2015-06-12 17:43:14.266 XYZPersonTest[1394:111923] 0


Copying Data Objects

NSData,NSMutableData支持 NSCopy 和 NSMutableCopy

可以使用 copy 来创建 readonly 对象

用 mutableCopy 创建可修改对象


Saving Data Objects

[data1 writeToFile:@"/Users/adolsai/Public/Demo/readme.txt" atomically:YES];

atomically:是 NO 的时候直接写入到指定文件, YES 的时候写到缓存文件再 rename 过去



Working With Mutable Binary Data

大概也就是增删改查什么的

Modifying Bytes

mutableBytes方法返回可读写的内部数据指针, setLength可以直接删去后面一段数据或者正常数据长度

NSMutableData *data1, *data2;
NSString *myString = @"string for data1";
NSString *yourString = @"string for data2";
const char *utfMyString = [myString UTF8String];
const char *utfYourString = [yourString UTF8String];
unsigned char *firstBuffer, *secondBuffer[20];

data1 = [NSMutableData dataWithBytes:utfMyString length:strlen(utfMyString)];
data2 = [NSMutableData dataWithBytes:utfYourString length:strlen(utfYourString)];

[data2 getBytes:secondBuffer length:20];

NSLog(@"data2 before:\"%s\"\n",(char *)secondBuffer);
//OUTPUT: data2 before:"string for data2"

firstBuffer = [data2 mutableBytes];
[data1 getBytes:firstBuffer length:[data2 length]];

NSLog(@"data1 before:\"%s\"\n",(char *)firstBuffer);
//OUTPUT: data1 before:"string for data1"

[data2 getBytes:secondBuffer length:20];

NSLog(@"data2 after: \"%s\"\n", (char *)secondBuffer);
//OUTPUT: data2 after: "string for data1"

Appending Bytes

appendBytes:length:

appendData:

NSMutableData *data1, *data2;
NSString *firstString = @"ABCD";
NSString *secondString = @"EFGH";
const char *utfFirstString = [firstString UTF8String];
const char *utfSecondString = [secondString UTF8String];
unsigned char *aBuffer;
unsigned long len;

data1 = [NSMutableData dataWithBytes:utfFirstString length:strlen(utfFirstString)];
data2 = [NSMutableData dataWithBytes:utfSecondString length:strlen(utfSecondString)];

len = [data2 length];
aBuffer = malloc(len);

[data2 getBytes:aBuffer length:[data2 length]];
[data1 appendBytes:aBuffer length:len];

NSLog(@"%s",[data1 bytes]);
//OUTPUT: ABCDEFGH


Replacing Bytes

resetBytesInRange:

replaceBytesInRange:withBytes:

NSMutableData *data1,*data2;
NSString *myString = @"Dio and JOJO";
NSString *yourString = @"Sisha";
const char *utfMyString = [myString UTF8String];
const char *utfYourString = [yourString UTF8String];
unsigned long len;
unsigned char *aBuffer;
NSRange range = {8, strlen(utfYourString)};

data1 = [NSMutableData dataWithBytes:utfMyString length:strlen(utfMyString)];
data2 = [NSMutableData dataWithBytes:utfYourString length:strlen(utfYourString)];

len = [data2 length];
aBuffer = malloc(len);

[data2 getBytes:aBuffer length:len];
[data1 replaceBytesInRange:range withBytes:aBuffer];

NSLog(@"%s",[data1 bytes]);
//OUTPUT: Dio and Sisha


标签:ios, object-c, nsdata