在Swift 3中提取Data对象的片段

时间:2016-12-11 03:42:22

标签: ios swift swift3

我有一个60字节Data流,如下所示

let myDataStream = Data(bytes: [24, 163, 209, 194, 255, 1, 184, 230, 37, 208, 140, 201, 6, 0, 64, 0, 7, 98, 108, 117, ...])

字节#1(索引0)表示第一个对象的长度,因此在这种情况下,第一个对象由前24个对象组成,包括字节#1

我尝试了很多方法,但我一直无法弄清楚

  1. 如何将前24个字节提取到新的数据对象

  2. 如果#1完成后,如何从myDataStream删除前24个字节。字节#25将再次具有下一个对象的大小

  3. 我最接近解决#1是

    let streamLength = Int(myDataStream[0])
    let newStream = Data(bytes: myDataStream[0...streamLength])
    

    但是我收到一条错误,指出cannot invoke initializer for Data with Data.subsequence

3 个答案:

答案 0 :(得分:8)

您可以结合使用subdataremoveSubRange方法来达到理想的效果。

subData(in:)Data结构上的实例方法。

removeSubRange()也是Data结构上的实例方法。

您可以在此处详细了解这些方法:https://developer.apple.com/reference/foundation/data

示例方法:

func extract(from data: inout Data) -> Data? {
    guard data.count > 0 else {
        return nil
    }

    // Define the length of data to return
    let length = Int.init(data[0])

    // Create a range based on the length of data to return
    let range = Range(0..<length)

    // Get a new copy of data
    let subData = data.subdata(in: range)

    // Mutate data
    data.removeSubrange(range)

    // Return the new copy of data
    return subData
}

<强>用法:

// Data (27 bytes)
var data = Data(bytes: [24, 163, 209, 194, 255, 1, 184, 230, 37, 208, 140, 201, 6, 0, 64, 0, 7, 98, 108, 117, 42, 63, 78, 200, 3, 34, 36])

// First extraction
let first = extract(from: &data)
print(first!) // Prints 24 bytes
print(data) // Prints 3 bytes

// Second extraction
let second = extract(from: &data)
print(second!) // Prints 3 bytes
print(data) // Prints 0 bytes

// Third extraction
let third = extract(from: &data)
print(third ?? "No Data") // Prints "No Data"

进行推广

您还可以将extract方法包含在Data的扩展名中,如下所示:

extension Data {
    mutating func extract() -> Data? {
        guard self.count > 0 else {
            return nil
        }

        // Define the length of data to return
        let length = Int.init(self[0])

        // Create a range based on the length of data to return
        let range = Range(0..<length)

        // Get a new copy of data
        let subData = self.subdata(in: range)

        // Mutate data
        self.removeSubrange(range)

        // Return the new copy of data
        return subData
    }
}

然后你可以使用这样的方法:

// Data (27 bytes)
var data = Data(bytes: [24, 163, 209, 194, 255, 1, 184, 230, 37, 208, 140, 201, 6, 0, 64, 0, 7, 98, 108, 117, 42, 63, 78, 200, 3, 34, 36])

// First extraction
let first = data.extract()
print(first!) // Prints 24 bytes
print(data) // Prints 3 bytes

// Second extraction
let second = data.extract()
print(second!) // Prints 3 bytes
print(data) // Prints 0 bytes

// Third extraction
let third = data.extract()
print(third ?? "No Data") // Prints "No Data"

答案 1 :(得分:2)

Data具有处理subdata的专用函数:

let streamLength = Int(myDataStream[0])
let newStream = myDataStream.subdata(in: 1..<streamLength + 1)
let nextStream = myDataStream.subdata(in: streamLength + 1..<myDataStream.count)

答案 2 :(得分:0)

您可能正在寻找InputStream.

undefined method `emoji_flag' for #<ISO3166::Country:0x007fe87145d7e0>