将字节读入Swift字符串

时间:2014-09-15 03:01:54

标签: ios utf-8 swift nsinputstream

我有一个包含以下数据的二进制文件test.data:

01 E6 B5 8B E8 AF 95 02

第一个字节只是序列号01.接下来的6个字节是两个UTF8中文字符"测试"然后第8个字节又是另一个序列号02.

据我所知,UTF8是可变长度(1-4字节)。请参阅此post

我使用以下代码读取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))
    }

我想写一个从流中读取字符串的方法。以下是我的想法:

  • 读取字节(假设我知道要读取多少字节)
  • 将字节转换为字符
  • 将字符附加到字符串

但问题是要为Character读取多少字节,因为UTF8长度是变体?一般来说,我的问题是我应该如何读取UTF8字符串?提前谢谢。

2 个答案:

答案 0 :(得分:4)

只需读取UnsafeMutablePointer缓冲区并将其转换为String。返回的String将是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

    }
}

答案 1 :(得分:4)

以下是我对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

  }
}