Байты изменяются после кодирования NSString в NSInputStream через NSData

Я столкнулся со следующей проблемой при попытке закодировать NSString как NSString -> NSData -> NSInputStream, а затем декодировать из NSInputStream методом read:

NSString *inputString = [NSString stringWithFormat:@"%c", 255];
NSData *data = [inputString dataUsingEncoding:NSUTF8StringEncoding];
NSInputStream *stream = [NSInputStream inputStreamWithData:data];
[stream open];
uint8_t bytes;
[stream read:&bytes maxLength:1];
NSLog(@"%i", bytes);

Вывод 195 вместо 255. Почему?


person yvetterowe    schedule 18.10.2016    source источник


Ответы (1)


Из-за типа кодировки, которую вы использовали для строки. UTF-8 — это форма кодирования строк, которая в конечном итоге преобразует символы со значениями выше 127 в многобайтовые последовательности. Таким образом, хотя inputString содержит один символ, ваш объект данных на самом деле содержит не один байт, как вы могли предположить, а несколько (в данном случае два) байта. А когда вы читаете из потока, вы читаете только первый байт закодированных данных, а там было больше.

Вам не нужно было прогонять данные через входной поток, чтобы увидеть этот результат. Доступ к первому байту экземпляра NSData показал бы то же самое.

Вы говорите, что это «проблема», но не предлагаете, чего на самом деле пытаетесь достичь. 255 не является печатным/значимым текстовым символом. Если вы хотите передавать необработанные байты данных, вы можете сделать это напрямую, а не использовать NSString и строковые кодировки. Если вы передаете строки, то это уже правильно. Вам просто нужно быть готовым к тому, что размер ваших данных может превышать "длину" вашей строки.

person Ben Zotto    schedule 18.10.2016
comment
TIL, спасибо за объяснение! Это часть моего модульного теста, и я ожидал что-то вроде XCTAssertEqual((int)bytes, 255); . - person yvetterowe; 18.10.2016
comment
Без проблем. Похоже, это просто бесполезный тест. Удачи. - person Ben Zotto; 18.10.2016