我想用BEncoding ObjC class来解码.torrent文件.

NSData *rawdata = [NSData dataWithContentsOfFile:@"/path/to/the.torrent"];
NSData *torrent = [BEncoding objectFromEncodedData:rawdata];

当我NSLog torrent时,我得到以下信息:

{
    announce = <68747470 3a2f2f74 6f727265 6e742e75 62756e74 752e636f 6d3a3639 36392f61 6e6e6f75 6e6365>;
    comment = <5562756e 74752043 44207265 6c656173 65732e75 62756e74 752e636f 6d>;
    "creation date" = 1225365524;
    info =     {
        length = 732766208;
        name = <7562756e 74752d38 2e31302d 6465736b 746f702d 69333836 2e69736f>;
        "piece length" = 524288;
....

如何将name转换为NSString?我试过了..

NSData *info = [torrent valueForKey:@"info"];
NSData *name = [info valueForKey:@"name"];
unsigned char aBuffer[[name length]];
[name getBytes:aBuffer length:[name length]];
NSLog(@"File name: %s", aBuffer);

…它会重新检索数据,但之后似乎有额外的unicode垃圾:

File name: ubuntu-8.10-desktop-i386.iso)

我也试过(from here)..

NSString *secondtry = [NSString stringWithCharacters:[name bytes] length:[name length] / sizeof(unichar)];

但这似乎返回了一堆随机字符:

扵湵畴㠭ㄮⴰ敤歳潴⵰㍩㘸椮潳

第一种方法(如Apple文档中所述)正确返回了大部分数据,并添加了一些字节,这一事实让我认为这可能是BEncoding库中的一个错误..但我对ObjC缺乏了解更可能是我的错..

推荐答案

NSData *torrent = [BEncoding objectFromEncodedData:rawdata];

当我登录torrent时,我得到以下信息:

{
    ⋮
}

那将是一本NSDictionary,而不是NSData.

unsigned char aBuffer[[name length]];
[name getBytes:aBuffer length:[name length]];
NSLog(@"File name: %s", aBuffer);

…它会重新检索数据,但之后似乎有额外的unicode垃圾:

File name: ubuntu-8.10-desktop-i386.iso)

不,它很好地检索到了文件名;你只是把它打印错了.%s接受以null结尾的C字符串;数据对象的字节不是以null结尾的(它们只是字节,在任何编码中都不一定是字符,0是null,因为字符是完全有效的字节).您必须再分配一个字符,并将数组中的最后一个字符设置为0:

size_t length = [name length] + 1;
unsigned char aBuffer[length];
[name getBytes:aBuffer length:length];
aBuffer[length - 1] = 0;
NSLog(@"File name: %s", aBuffer);

但是,在NSData对象中以null终止数据是错误的(除非您需要C字符串).我马上就到.

我也试过[…]..

NSString *secondtry = [NSString stringWithCharacters:[name bytes] length:[name length] / sizeof(unichar)];

但这似乎会返回随机的汉字:

扵湵畴㠭ㄮⴰ敤歳潴⵰㍩㘸椮潳

这是因为您的字节是UTF-8,它(通常)在一个字节中编码一个字符.

unichar是UTF-16,stringWithCharacters:length:接受UTF-16.在这种编码中,一个字符(通常)是两个字节.(因此除以sizeof(unichar):它将字节数除以2得到字符数.)

所以你说"这是一些UTF-16数据",然后它每两个字节生成一个字符;每对字节应该是两个字符,而不是一个字符,所以你得到了垃圾(结果大部分是CJK表意文字).


You answered your own question很好,但对于UTF-8编码的字符串,stringWithUTF8String:stringWithCString:encoding:简单.

然而,当你有了长度(就像你有NSData时一样),使用initWithBytes:length:encoding:就更容易、更合适了.它更容易,因为它不需要以null结尾的数据;它只是使用你已经拥有的长度.(不要忘记释放或自动释放.)

Objective-c相关问答推荐

Objective-C NSMutableArray 在枚举时发生了变异?

检测时间格式是 12 小时还是 24 小时格式

iphone 的 UIPopoverController 不工作?

如何追踪 SIGABRT 的原因

NSPredicate 与整数比较

iOS - 应用程序关闭时的核心位置和地理围栏

iOS 正确使用 @weakify(self) 和 @strongify(self)

主队列上的 dispatch_sync 在单元测试中挂起

NSUInteger 不应该在格式字符串中使用吗?

Objective-C:如何使用 BOOL 类型的参数调用 performSelector?

Container View 好像有 UINavigationBar 一样被下推?

CoreData 关系故障?

如何删除应用程序指定目录中的所有文件?

在 Cocoa 中你更喜欢 NSInteger 还是 int,为什么?

如何保存我的 iPhone 应用程序的用户首选项?

UITabBar 未在 ios 7 中显示所选项目图像

在Objective-C中替换字符串中的一个字符

为什么不鼓励使用伞式框架?

Objective-C 中的属性和实例变量

Objective-C in,out,inout,byref,byval, .. 等等.这些是什么?