Читайте байты в быстрой строке
У меня есть двоичный файл test.data, содержащий следующие данные:
01 E6 B5 8B E8 AF 95 02
Первый байт - это, например, порядковый номер 01. Следующие 6 байтов - это два китайских символа UTF8 "测试". Затем 8-й байт снова является другим порядковым номером 02.
Как я знаю, UTF8 имеет переменную длину (1-4 байта). Пожалуйста, обратитесь к этому сообщению.
Я использую следующий код для чтения Int32 и Byte(UInt8):
extension NSInputStream
{
func readInt32() -> Int
{
var readBuffer = Array<UInt8>(count:sizeof(Int32), repeatedValue: 0)
var numberOfBytesRead = self.read(&readBuffer, maxLength: readBuffer.count)
return Int(readBuffer[0]) << 24 |
Int(readBuffer[1]) << 16 |
Int(readBuffer[2]) << 8 |
Int(readBuffer[3])
}
func readByte() -> Byte {
var readBuffer : Byte = 0
return self.read(&readBuffer, maxLength: sizeof(UInt8))
}
Я хотел бы написать метод для чтения строк из потока. Вот что я думаю:
- Чтение байтов (предположим, я знаю, сколько байтов нужно прочитать)
- Преобразовать байты в символ
- Добавить символ в строку
Но проблема в том, сколько байтов нужно прочитать для символа, потому что длина UTF8 является вариантом? В общем, мой вопрос, как я должен читать UTF8 String? Заранее спасибо.
2 ответа
Просто прочитайте в буфер UnsafeMutablePointer и преобразуйте его в строку. Возвращенная строка будет UTF8.
extension NSInputStream
{
public func readString(length:Int) -> String {
var str = ""
if length > 0 {
var readBuffer = UnsafeMutablePointer<UInt8>.alloc(length+1)
var numberOfBytesRead = self.read(readBuffer, maxLength: length)
if numberOfBytesRead == length {
var buf = UnsafeMutablePointer<CChar>(readBuffer)
buf[length] = 0
// the C String must be null terminated
if let utf8String = String.fromCString(buf) {
str = utf8String
}
}
readBuffer.dealloc(length)
}
return str
}
}
Вот исправленная версия, которую я упомянул в своем комментарии к сообщению bagusflyer:
extension NSInputStream
{
public func readString(length:Int) -> String {
var str = ""
if length > 0 {
var readBuffer = UnsafeMutablePointer<UInt8>.alloc(length+1)
var numberOfBytesRead = self.read(readBuffer, maxLength: length)
// modified this from == length to > 0
if numberOfBytesRead > 0 {
var buf = UnsafeMutablePointer<CChar>(readBuffer)
buf[numberOfBytesRead] = 0
// the C String must be null terminated
if let utf8String = String.fromCString(buf) {
str = utf8String
}
}
readBuffer.dealloc(length+1)
}
return str
}
}