[英]Swift Data to Int array
I'd like to access the raw bytes in Data as an array of numeric types for quick parsing.我想访问 Data 中的原始字节作为数字类型的数组以进行快速解析。 I have lots of data to parse, so I'm looking for efficiency.
我有很多数据要解析,所以我正在寻找效率。 Data is a mix of shorts, ints, longs, and doubles.
数据是短裤、整数、长裤和双打的混合。
The below code seems to work and be fast, but I'm getting deprecated warning: 'withUnsafeBytes' is deprecated下面的代码似乎可以工作并且速度很快,但是我收到了弃用警告:'withUnsafeBytes' is deprecated
I can't figure out the updated way to treat the underlying bytes as an array of numbers for quick lookup.我想不出将底层字节视为数字数组以进行快速查找的更新方法。
var data: Data = ...
// create "virtual" arrays of different types to directly access bytes (without copying bytes)
let ushortArray: [UInt16] = data.withUnsafeBytes {
[UInt16](UnsafeBufferPointer(start: $0, count: data.count/2))
}
let intArray: [Int32] = data.withUnsafeBytes {
[Int32](UnsafeBufferPointer(start: $0, count: data.count/4))
}
// Access data simply
var i1: UInt16 = ushortArray[0]
var i2: Int32 = intArray[1]
PS I'm not concerned with big/little endian PS 我不关心大/小端
If you want to load it as an Array what you need is to use UnsafeRawBufferPointer
bindMemory
method to the type you want.如果你想将它作为一个数组加载,你需要的是将
UnsafeRawBufferPointer
bindMemory
方法用于你想要的类型。 you can also extend ContiguousBytes to make a generic method and simplify your syntax:您还可以扩展 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($0.bindMemory(to: T.self)) } }
var uInt16Array: [UInt16] { objects() }
var int32Array: [Int32] { objects() }
}
extension Array {
var data: Data { withUnsafeBytes { .init($0) } }
}
Usage:用法:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.