将NSData字节转换为NSString? [英] Convert NSData bytes to NSString?

查看:140
本文介绍了将NSData字节转换为NSString?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 BEncoding ObjC类以解码 .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;
....

如何转换 / code>成一个NSString?我已尝试..

How do I convert the name into a NSString? I have tried..

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垃圾后:

..which retrives the data, but seems to have additional unicode rubbish after it:

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

我也试过了(从这里

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

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

..but this seems to return a bunch of random characters:

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

事实上,第一种方式(如苹果文档中提到的)返回大多数数据正确,与一些额外的字节使我认为这可能是一个错误在BEncoding库..但我缺乏关于ObjC的知识更有可能出错。

The fact the first way (as mentioned in the Apple documentation) returns most of the data correctly, with some additional bytes makes me think it might be an error in the BEncoding library.. but my lack of knowledge about ObjC is more likely to be at fault..

推荐答案


NSData *torrent = [BEncoding objectFromEncodedData:rawdata];

当我NSLog种子我得到以下:

When I NSLog torrent I get the following:

{
    ⋮
}


这将是NSDictionary,然后是NSData。

That would be an NSDictionary, then, not an NSData.


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

..它检索数据,但似乎有额外的unicode垃圾后:

..which retrives the data, but seems to have additional unicode rubbish after it:

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


不,它检索的文件名很好;你只是打印不正确。 %s 采用一个C字符串,以null结尾;数据对象的字节不是空终止的(它们只是字节,不一定是任何编码中的字符,0-作为字符为空 - 是完全有效的字节)。您必须再分配一个字符,并将数组中的最后一个字符设置为0:

No, it retrieved the filename just fine; you simply printed it incorrectly. %s takes a C string, which is null-terminated; the bytes of a data object are not null-terminated (they are just bytes, not necessarily characters in any encoding, and 0—which is null as a character—is a perfectly valid byte). You would have to allocate one more character, and set the last one in the array to 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字符串)。

But null-terminating the data in an NSData object is wrong (except when you really do need a C string). I'll get to the right way in a moment.


我也试过了[...] ..

I have also tried […]..

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

..但这似乎返回随机汉字:

..but this seems to return random Chinese characters:

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


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

That's because your bytes are UTF-8, which encodes one character in (usually) one byte.

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

unichar is, and stringWithCharacters:length: accepts, UTF-16. In that encoding, one character is (usually) two bytes. (Hence the division by sizeof(unichar): it divides the number of bytes by 2 to get the number of characters.)

所以你说这里有一些UTF-16数据,它从每两个字节开始创建字符;每对字节应该是两个字符,而不是一个,所以你有垃圾(结果是大多是CJK表意文字)。

So you said "here's some UTF-16 data", and it went and made characters from every two bytes; each pair of bytes was supposed to be two characters, not one, so you got garbage (which turned out to be mostly CJK ideographs).

您回答了自己的问题相当不错,除非对于UTF-8编码的字符串, stringWithUTF8String: stringWithCString:encoding:更简单。

You answered your own question pretty well, except that stringWithUTF8String: is simpler than stringWithCString:encoding: for UTF-8-encoded strings.

然而,当你有长度(就像你有一个NSData),使用 initWithBytes:length:encoding更容易,更恰当 - 。它更容易,因为它不需要null终止的数据;它只是使用你已经有的长度。 (不要忘记释放或自动释放它。)

However, when you have the length (as you do when you have an NSData), it is even easier—and more proper—to use initWithBytes:length:encoding:. It's easier because it does not require null-terminated data; it simply uses the length you already have. (Don't forget to release or autorelease it.)

这篇关于将NSData字节转换为NSString?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆