Swift 数据到 Int 数组
Swift Data to Int array
我想以数字类型数组的形式访问数据中的原始字节以进行快速解析。我有很多数据要解析,所以我正在寻找效率。数据是短裤、整数、长裤和双打的混合。
下面的代码似乎可以运行并且速度很快,但是我收到了已弃用的警告:'withUnsafeBytes' 已弃用
我想不出将底层字节视为数字数组以便快速查找的更新方法。
var data: Data = ...
// create "virtual" arrays of different types to directly access bytes (without copying bytes)
let ushortArray: [UInt16] = data.withUnsafeBytes {
[UInt16](UnsafeBufferPointer(start: [=11=], count: data.count/2))
}
let intArray: [Int32] = data.withUnsafeBytes {
[Int32](UnsafeBufferPointer(start: [=11=], count: data.count/4))
}
// Access data simply
var i1: UInt16 = ushortArray[0]
var i2: Int32 = intArray[1]
P.S。我不关心 big/little endian
如果您想将其作为数组加载,您需要使用 UnsafeRawBufferPointer
bindMemory
方法来指定您想要的类型。您还可以扩展 ContiguousBytes 以创建通用方法并简化语法:
Note: if you are planing to get a subsequence of your data make sure to do NOT subscript the data to avoid misaligned errors. You need to use Data subdata method instead.
extension ContiguousBytes {
func objects<T>() -> [T] { withUnsafeBytes { .init([=10=].bindMemory(to: T.self)) } }
var uInt16Array: [UInt16] { objects() }
var int32Array: [Int32] { objects() }
}
extension Array {
var data: Data { withUnsafeBytes { .init([=11=]) } }
}
用法:
let uInt16Array: [UInt16] = [.min, 1, 2, 3, .max] // [0, 1, 2, 3, 65535]
let int32Array: [Int32] = [.min, 1, 2, 3, .max] // [-2147483648, 1, 2, 3, 2147483647]
let uInt16ArrayData = uInt16Array.data // 10 bytes
let int32ArrayData = int32Array.data // 20 bytes
let uInt16ArrayLoaded = uInt16ArrayData.uInt16Array // [0, 1, 2, 3, 65535]
let int32ArrayLoaded = int32ArrayData.int32Array // [-2147483648, 1, 2, 3, 2147483647]
// Access data simply
let i1 = uInt16ArrayLoaded[0] // UInt16 0
let i2 = int32ArrayLoaded[0] // Int32 -2147483648
let i3 = uInt16ArrayLoaded[4] // UInt16 65535
let i4 = int32ArrayLoaded[4] // Int32 2147483647
我想以数字类型数组的形式访问数据中的原始字节以进行快速解析。我有很多数据要解析,所以我正在寻找效率。数据是短裤、整数、长裤和双打的混合。
下面的代码似乎可以运行并且速度很快,但是我收到了已弃用的警告:'withUnsafeBytes' 已弃用
我想不出将底层字节视为数字数组以便快速查找的更新方法。
var data: Data = ...
// create "virtual" arrays of different types to directly access bytes (without copying bytes)
let ushortArray: [UInt16] = data.withUnsafeBytes {
[UInt16](UnsafeBufferPointer(start: [=11=], count: data.count/2))
}
let intArray: [Int32] = data.withUnsafeBytes {
[Int32](UnsafeBufferPointer(start: [=11=], count: data.count/4))
}
// Access data simply
var i1: UInt16 = ushortArray[0]
var i2: Int32 = intArray[1]
P.S。我不关心 big/little endian
如果您想将其作为数组加载,您需要使用 UnsafeRawBufferPointer
bindMemory
方法来指定您想要的类型。您还可以扩展 ContiguousBytes 以创建通用方法并简化语法:
Note: if you are planing to get a subsequence of your data make sure to do NOT subscript the data to avoid misaligned errors. You need to use Data subdata method instead.
extension ContiguousBytes {
func objects<T>() -> [T] { withUnsafeBytes { .init([=10=].bindMemory(to: T.self)) } }
var uInt16Array: [UInt16] { objects() }
var int32Array: [Int32] { objects() }
}
extension Array {
var data: Data { withUnsafeBytes { .init([=11=]) } }
}
用法:
let uInt16Array: [UInt16] = [.min, 1, 2, 3, .max] // [0, 1, 2, 3, 65535]
let int32Array: [Int32] = [.min, 1, 2, 3, .max] // [-2147483648, 1, 2, 3, 2147483647]
let uInt16ArrayData = uInt16Array.data // 10 bytes
let int32ArrayData = int32Array.data // 20 bytes
let uInt16ArrayLoaded = uInt16ArrayData.uInt16Array // [0, 1, 2, 3, 65535]
let int32ArrayLoaded = int32ArrayData.int32Array // [-2147483648, 1, 2, 3, 2147483647]
// Access data simply
let i1 = uInt16ArrayLoaded[0] // UInt16 0
let i2 = int32ArrayLoaded[0] // Int32 -2147483648
let i3 = uInt16ArrayLoaded[4] // UInt16 65535
let i4 = int32ArrayLoaded[4] // Int32 2147483647