NSData 数据对象

NSData : NSObject

初始化

  • 准备数据
    int len = 2;
    Byte *bytes = malloc(sizeof(Byte) * len);
    bytes[0] = 0x00;
    bytes[1] = 0x0f;
    
    // 栈
    Byte bytes2[] = {0x01, 0x02};
  • 初始化 1
    NSData *data1 = [NSData data];
  • 初始化 2
    NSData *data2 = [NSData dataWithBytes:bytes length:2];// bytes free 后 不影响 data2
    free(bytes1);
  • 初始化 3
    NSData *data3 = [NSData dataWithBytesNoCopy:bytes length:2];// bytes free 后 影响 data3
    free(bytes1);
  • 初始化 4
    NSData *data4 = [NSData dataWithBytesNoCopy:bytes length:2 freeWhenDone:YES];// 可以接管 free
  • 初始化 5
    NSData *data5 = [NSData dataWithData:data1];

读取文件 data

  • 准备本地文件
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"pdf"];
  • 无参数模式
    NSData *data = [NSData dataWithContentsOfFile:filePath];
    NSData *data2 = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath]];
  • 参数模式
    NSError *error;
    NSData *data3 = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
    NSData *data4 = [NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath] options:NSDataReadingMappedIfSafe error:&error];

//    typedef NS_OPTIONS(NSUInteger, NSDataReadingOptions) {
//        NSDataReadingMappedIfSafe =   1UL << 0,    // 安全的情况下,使用文件映射(不加入内存)
//        NSDataReadingUncached = 1UL << 1,    // 加入内存
//        NSDataReadingMappedAlways = 1UL << 3,    // 总是不加入内存
//    };

写入文件

  • 准备文件 data
    UIImage *image = [UIImage imageNamed:@"image"];
    NSData *imageData = UIImagePNGRepresentation(image);
    NSString *filePath = [NSString stringWithFormat:@"%@/image.png",NSHomeDirectory()];
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath];
  • 一般
    BOOL res1 = [imageData writeToFile:filePath atomically:NO];
    BOOL res2 = [imageData writeToURL:fileUrl atomically:YES];
  • 复杂
    NSError *error;
    BOOL res3 = [imageData writeToFile:filePath options:NSDataWritingAtomic error:&error];
    BOOL res4 = [imageData writeToURL:fileUrl options:NSDataWritingWithoutOverwriting error:&error];

//    typedef NS_OPTIONS(NSUInteger, NSDataWritingOptions) {
//        NSDataWritingAtomic = 1UL << 0, // 覆盖
//        NSDataWritingWithoutOverwriting = 1UL << 1, // 不覆盖,已存在时,返回 NO
//        NSDataWritingFileProtectionNone = 0x10000000, // 以下都是 文件保护 相关
//        NSDataWritingFileProtectionComplete = 0x20000000,
//        NSDataWritingFileProtectionCompleteUnlessOpen = 0x30000000,
//        NSDataWritingFileProtectionCompleteUntilFirstUserAuthentication = 0x40000000,
//        NSDataWritingFileProtectionMask = 0xf0000000,
//    };

Base64 处理

  • 准备 data
    Byte bytes[] = {
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,

        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,

        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04,
        0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04
    };
    NSData *data = [NSData dataWithBytes:bytes length:96];
  • data <-> base64String
    NSString *base64String1 = [data base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

//    typedef NS_OPTIONS(NSUInteger, NSDataBase64EncodingOptions) {
//        2 选 1,64\76 长度分割
//        NSDataBase64Encoding64CharacterLineLength = 1UL << 0,
//        NSDataBase64Encoding76CharacterLineLength = 1UL << 1,
//
//        下面 2 个参数,默认都有,也就是默认添加 \r\n
//        NSDataBase64EncodingEndLineWithCarriageReturn = 1UL << 4, // 添加 \r
//        NSDataBase64EncodingEndLineWithLineFeed = 1UL << 5,// 添加 \n
//    }


    NSData *data1 = [[NSData alloc] initWithBase64EncodedString:base64String1 options:NSDataBase64DecodingIgnoreUnknownCharacters];

//    typedef NS_OPTIONS(NSUInteger, NSDataBase64DecodingOptions) {
//        NSDataBase64DecodingIgnoreUnknownCharacters = 1UL << 0// 没的选,自动识别了
//    }
  • data <-> base64data
    // 与 string 转换类似
    NSData *base64Data = [data base64EncodedDataWithOptions:NSDataBase64Encoding64CharacterLineLength];
    NSData *data5 = [[NSData alloc] initWithBase64EncodedData:base64Data options:NSDataBase64DecodingIgnoreUnknownCharacters];

Bytes 处理

  • 准备数据
    int len = 10;
    Byte *bytes1 = malloc(sizeof(Byte) * len);
    bytes1[0] = 0x00;
    bytes1[1] = 0x01;
    bytes1[2] = 0x02;
    bytes1[3] = 0x03;
    bytes1[4] = 0x04;
    bytes1[5] = 0x05;
    bytes1[6] = 0x06;
    bytes1[7] = 0x07;
    bytes1[8] = 0x08;
    bytes1[9] = 0x09;
    NSData *data = [NSData dataWithBytes:bytes1 length:len];
  • 获取完整 bytes[]
    Byte *dataBytes = (Byte *)data.bytes;
    NSString *newHexStr = [NSString stringWithFormat:@"%x",dataBytes[1]&0xff];///16进制数
    NSLog(@"%@", newHexStr);
  • 获取部分 bytes[]
    Byte *subBytes1 = malloc(sizeof(Byte) * 10);
    [data getBytes:subBytes1 length:10];
    NSLog(@"%@", [NSData dataWithBytes:subBytes1 length:10]);
    
    Byte *subBytes2 = malloc(sizeof(Byte) * 3);
    [data getBytes:subBytes2 range:NSMakeRange(2, 3)];
    NSLog(@"%@", [NSData dataWithBytes:subBytes2 length:3]);

  • 遍历(简单测试发现,byteRange 就是完整 data,拼接的复杂 data 会遍历出来?暂时不清楚)
    [data enumerateByteRangesUsingBlock:^(const void * _Nonnull bytes, NSRange byteRange, BOOL * _Nonnull stop) {
        NSLog(@"%@", NSStringFromRange(byteRange));
        NSLog(@"%s", bytes);
    }];

数据查找

  • 准备数据
    int len1 = 20;
    Byte *bytes1 = malloc(sizeof(Byte) * len1);
    bytes1[0] = 0x00;
    bytes1[1] = 0x01;
    bytes1[2] = 0x02;
    bytes1[3] = 0x03;
    bytes1[4] = 0x04;
    bytes1[5] = 0x05;
    bytes1[6] = 0x06;
    bytes1[7] = 0x07;
    bytes1[8] = 0x08;
    bytes1[9] = 0x09;
    bytes1[10] = 0x00;
    bytes1[11] = 0x01;
    bytes1[12] = 0x02;
    bytes1[13] = 0x03;
    bytes1[14] = 0x04;
    bytes1[15] = 0x05;
    bytes1[16] = 0x06;
    bytes1[17] = 0x07;
    bytes1[18] = 0x08;
    bytes1[19] = 0x09;
    
    NSData *data1 = [NSData dataWithBytes:bytes1 length:len1];
  • 获取部分数据
    NSData *subData = [data1 subdataWithRange:NSMakeRange(2, 3)];
  • 查找部分数据的范围(可选条件)
//    typedef NS_OPTIONS(NSUInteger, NSDataSearchOptions) {
//        NSDataSearchBackwards = 1UL << 0, // 倒序
//        NSDataSearchAnchored = 1UL << 1 // 类似前缀(结合倒序用就是后缀)
//    }
  • 正向查找
    int len2 = 3;
    Byte *bytes2 = malloc(sizeof(Byte) * len2);
    bytes2[0] = 0x01;
    bytes2[1] = 0x02;
    bytes2[2] = 0x03;
    NSData *data2 = [NSData dataWithBytes:bytes2 length:len2];

    NSRange range2 = [data1 rangeOfData:data2 options:0 range:NSMakeRange(0, 20)];
  • 反向查找
    int len3 = 3;
    Byte *bytes3 = malloc(sizeof(Byte) * len3);
    bytes3[0] = 0x06;
    bytes3[1] = 0x07;
    bytes3[2] = 0x08;
    NSData *data3 = [NSData dataWithBytes:bytes3 length:len3];
    
    NSRange range3 = [data1 rangeOfData:data3 options:NSDataSearchBackwards range:NSMakeRange(0, 20)];
  • 前缀
    int len4 = 3;
    Byte *bytes4 = malloc(sizeof(Byte) * len4);
    bytes4[0] = 0x01;
    bytes4[1] = 0x02;
    bytes4[2] = 0x03;
    NSData *data4 = [NSData dataWithBytes:bytes4 length:len4];

    NSRange range4 = [data1 rangeOfData:data4 options:NSDataSearchAnchored range:NSMakeRange(1, 19)];
  • 后缀
    int len5 = 3;
    Byte *bytes5 = malloc(sizeof(Byte) * len5);
    bytes5[0] = 0x06;
    bytes5[1] = 0x07;
    bytes5[2] = 0x08;
    NSData *data5 = [NSData dataWithBytes:bytes5 length:len5];
    
    NSRange range5 = [data1 rangeOfData:data5 options:NSDataSearchAnchored | NSDataSearchBackwards range:NSMakeRange(0, 19)];

其他

    BOOL iseq = [data1 isEqualToData:data2];
    NSInteger len = data1.length;
    NSString *desc = data1.description;