从NSData获取NSString分别到达

时间:2011-12-21 17:43:04

标签: objective-c encoding nsstring nsdata

我正在编写一个程序,它使用多字节编码将NSData转换为NSString。 转换本身很容易,但问题是NSData是单独到达的(数据按顺序到达)。 就像

- (void) dataArrived:(NSData*) data{
    NSString* mystr = [[[NSString alloc] initWithData:data encoding:NSShiftJISStringEncoding] autorelease];
    // I want to parse string here and show some view as it arrives.
}

如果数据只包含8位字母,那么我正在解析多字节字符串数据。所以我想做的是将NSData从头转换为NSString,并将无效字节保存到dataArrived的下一次调用(由于SJIS字母为1或2个字节,因此最后1个字节可能会保留为NSShiftJISStringEncoding的无效字节。)

我想知道他们是否有任何有用的方法或功能来做到这一点。 理想的方法可以采用NSData和Encoding,并返回它在NSData中找到无效字节序列的位置。

3 个答案:

答案 0 :(得分:1)

您是否考虑过收集所有数据然后一次解码?如果您不必处理大量数据,这将比您提出的方法简单得多。

答案 1 :(得分:1)

因为Shift JIS是在1或2个字节上编码的,所以你可以假设:

  • 所有未处理的数据都是有效的Shift JIS字符串
  • 或第一个长度为1的字节是有效的Shift JIS字符串

因此,我们可以使用NSMutableData缓冲区来处理这样的数据:

- (void)dataArrived:(NSData*)data
{
    [_mutableData appendData:data];
    NSUInteger length = [_mutableData length];
    NSString *string = [[[NSString alloc] initWithData:_mutableData
                                              encoding:NSShiftJISStringEncoding] autorelease];

    if ( ! string && length )
    {
        // try without the last byte
        --length;
        string = [[[NSString alloc] initWithBytes:data.bytes
                                           length:length
                                         encoding:NSShiftJISStringEncoding] autorelease];
    }

    if ( ! string && length )
    {
        // we have a problem: the data are invalid
        return;
    }

    // remove processed bytes
    [_mutableData replaceBytesInRange:NSMakeRange(0, length) withBytes:NULL length:0];

    // now, we can append string
}

答案 2 :(得分:0)

如何存储所有收到的数据,然后从更新的数据中重新创建字符串?

@interface StringReceiver {
    NSMutableData *_allData;
}
@property (retain, readonly) NSString *string;
- (void)processData:(NSData *)d;
@end

@implementation StringReceiver
- (id)init {
    self = [super init];
    if(self != nil) {
        _allData = [NSMutableData new];
    }
    return self;
}

- (void)dealloc {
    [_allData release];
    [super dealloc];
}

- (NSString *)string {
    NSString *s;
    s = [[NSString alloc] initWithData:_allData encoding:NSShiftJISStringEncoding];
    return [s autorelease];
}

- (void)processData:(NSData *)myData {
    [_allData appendData:myData];
}
@end

现在,每当您拨打-[StringReceiver processData:]时,您都可以致电-[StringReceiver string]以获取更新的字符串。