2013-08-28 77 views
0

我有一个NSData对象,其中包含我需要的一些数据。我想要做的是找出数据“FF D8”的位置(JPEG数据的开头)如何检查NSData对象是否包含子NSData?

我该如何实现这样的工作?

+1

使用'-bytes'方法得到的指针数据,然后做一个循环,寻找0xff,如果发现它,检查是否后面跟着0xd8。 – zneak

+0

这是一种方法。但我想知道是否有更短的编码方式,比如NSString的rangeOfString:Oops,我只是发现NSData的方法'rangeOfData:options:range:'。似乎对我有用? –

回答

9

首先得到该范围内,则获得数据:

// The magic start data object is only created once safely and 
// then reused each time 
static NSData* magicStartData = nil; 
static dispatch_once_t onceToken; 
dispatch_once(&onceToken, ^{ 
    static const uint8_t magic[] = { 0xff, 0xd8 }; 
    magicStartData = [NSData dataWithBytesNoCopy:(void*)magic length:2 freeWhenDone:NO]; 
}); 

// assume data is the NSData with embedded data 
NSRange range = [data rangeOfData:magicStartData options:0 range:NSMakeRange(0, [data length])]; 
if (range.location != NSNotFound) { 
    // This assumes the subdata doesn't have a specific range and is just everything 
    // after the magic, otherwise adjust 
    NSData* subdata = [data subdataWithRange:NSMakeRange(range.location, [data length] - range.location)]; 
} 
+0

谢谢!顺便说一句,有没有什么办法像'静态NSdata * magicStartData = [NSData dataWithBytesNoCopy:{0xff,0xd8} length:2 freeWhenDone:NO];'使数据比较不变?由于这个“FF D8”数据不需要频繁分配。 –

+0

@AndrewChang你可以用'dispatch_once'调用。我会更新我的答案以表明这是一个例子。 –

+0

哇,我以前还不知道这个功能。另一个新的知识,谢谢! –

1

尝试NSData rangeOfData:options:range:

NSData *data = /* Your data here */; 

    UInt8 bytes_to_find[] = { 0xFF, 0xD8 }; 
    NSData *dataToFind = [NSData dataWithBytes:bytes_to_find 
             length:sizeof(bytes_to_find)]; 

    NSRange range = [data rangeOfData:dataToFind 
           options:kNilOptions 
           range:NSMakeRange(0u, [data length])]; 

    if (range.location == NSNotFound) { 
     NSLog(@"Bytes not found"); 
    } 
    else { 
     NSLog(@"Bytes found at position %lu", (unsigned long)range.location); 
    }