我的 NSData 格式为“Hello$World$Image”($ 用作分隔符来区分不同的部分数据)我使用以下代码制作的
NSData *data=[@"$" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",data);
NSData *data2=[@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",data2);
NSData *data3=[@"World" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",data3);
NSData *dataImage=UIImagePNGRepresentation([UIImage imageNamed:@"Hello.png"]);
NSLog(@"%@",dataImage);
NSMutableData *mdata=[NSMutableData dataWithData:data2];
[mdata appendData:data];
[mdata appendData:data3];
[mdata appendData:data];
[mdata appendData:dataImage];
NSLog(@"%@",mdata);
由此,我得到了具有格式 Hello$World$Image 的字节的 mdata 变量,
现在我想要反转这件事,并希望将 Hello 作为 string1,将 World 作为 String2,并将 Image 存储在某个路径中,但我没有得到如何解析“$”的 NSData 并取出不同的组件。任何帮助将不胜感激。提前致谢
最佳答案
鉴于您对 $
感到困惑的评论分隔格式,请引用 Binary Data Programming Guide它描述了如何从 NSData
中提取二进制数据.一、创建$
分隔 NSData
,你可以这样做:
NSString *path = [[NSBundle mainBundle] pathForResource:@"Hello" ofType:@"png"];
NSData *imageData = [NSData dataWithContentsOfFile:path];
NSMutableData *data = [NSMutableData data];
[data appendData:[@"Hello" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"$" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"World" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:[@"$" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:imageData];
然后,要提取这两个字符串和图像,您可以:
NSUInteger len = [data length];
NSString *delimiterString = @"$";
NSData *delimiterData = [delimiterString dataUsingEncoding:NSUTF8StringEncoding];
NSRange firstDelimiterRange = [data rangeOfData:delimiterData
options:0
range:NSMakeRange(0, len)];
NSUInteger firstDelimiterIndex = firstDelimiterRange.location;
NSAssert(firstDelimiterIndex != NSNotFound, @"First delimiter not found");
NSRange secondDelimiterRange = [data rangeOfData:delimiterData
options:0
range:NSMakeRange(firstDelimiterIndex + 1, len - firstDelimiterIndex - 1)];
NSUInteger secondDelimiterIndex = secondDelimiterRange.location;
NSAssert(secondDelimiterIndex != NSNotFound, @"Second delimiter not found");
NSData *subdata1 = [data subdataWithRange:NSMakeRange(0, firstDelimiterIndex)];
NSString *string1 = [[NSString alloc] initWithData:subdata1 encoding:NSUTF8StringEncoding];
NSAssert(string1, @"string1 not found");
NSData *subdata2 = [data subdataWithRange:NSMakeRange(firstDelimiterIndex + 1, secondDelimiterIndex - firstDelimiterIndex - 1)];
NSString *string2 = [[NSString alloc] initWithData:subdata2 encoding:NSUTF8StringEncoding];
NSAssert(string2, @"string2 not found");
NSData *subdata3 = [data subdataWithRange:NSMakeRange(secondDelimiterIndex + 1, len - secondDelimiterIndex - 1)];
UIImage *image = [UIImage imageWithData:subdata3];
NSAssert(image, @"valid image not found");
下面我的原始答案集中在存储两个字符串和二进制图像的可能更好的方法上。鉴于您随后的评论,也许上面的丑陋代码可能对您有用,但我会保留我的原始答案以供将来引用。
几个想法:
$
),您可以构造您的 NSData
像这样:NSData *data=[@"$" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",data);
NSData *data2=[@"Hello" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",data2);
NSData *data3=[@"World" dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@",data3);
NSMutableData *mdata=[NSMutableData dataWithData:data2];
[mdata appendData:data];
[mdata appendData:data3];
NSLog(@"%@",mdata);
然后你可以像这样提取字符串:
NSString *fullString = [[NSString alloc] initWithData:mdata encoding:NSUTF8StringEncoding];
NSArray *components = [fullString componentsSeparatedByString:@"$"];
NSLog(@"components = %@", components);
但是,您不能使用
$
处理图像时使用分隔符,因为您无法保证您的 dataImage
可能没有 0x24
字节。 $
定界符,那么您必须对图像数据进行一些编码(例如通过base64),以确保它不会出现您的定界符。例如:// fill `NSData` with contents of the image data
NSString *path = [[NSBundle mainBundle] pathForResource:@"Hello" ofType:@"png"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSString *imageBase64String;
// base64 encode the binary data into a string format
if ([data respondsToSelector:@selector(base64EncodedStringWithOptions:)]) {
imageBase64String = [data base64EncodedStringWithOptions:0]; // iOS 7+
} else {
imageBase64String = [data base64Encoding]; // pre-iOS7
}
NSArray *array = @[@"Hello", @"World", imageBase64String];
NSString *finalString = [array componentsJoinedByString:@"$"];
NSData *finalData = [finalString dataUsingEncoding:NSUTF8StringEncoding];
显然,如果您在将图像添加到
$
时对图像进行 base-64 编码。分隔 NSData
,然后在另一端,您必须将 base-64 字符串解码回另一端的图像。但希望这能说明这个想法。 array
我之前的示例中的对象,然后您可以创建一个 NSData
JSON 表示为NSError *error = nil;
NSData *finalData = [NSJSONSerialization dataWithJSONObject:array options:0 error:&error];
NSAssert(finalData, @"Unable to dataWithJSONObject: %@", error);
这将生成如下所示的有效负载:
["Hello","World","iVBORw0KGgoAAAANSUh ... +Jyutq4AAAAASUVORK5CYII="]
或者,更好的是,您可以使用字典(它可以明确每个元素的功能用途),但希望您能明白:考虑使用完善的标准,如 JSON,为您的服务器创建有效负载。
NSData
要在您的应用程序中本地保存,更有效的机制是使用存档。因此,要创建一个 NSData
存档,您可以:NSArray *array = @[@"Hello", @"World", [UIImage imageNamed:@"Hello.png"]];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
然后,要从此文件中提取结果:
NSArray *results = [NSKeyedUnarchiver unarchiveObjectWithData:data];
如需更多信息,请参阅 Archives and Serializations Programming Guide .
但是鉴于您对希望将其发送到服务器的评论,存档可能不是正确的解决方案。
关于ios - 从 NSData : NSData Parsing 中查找不同的组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20761012/