Читайте байты в быстрой строке

У меня есть двоичный файл 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

  }
}
Другие вопросы по тегам