Swift操作字节数据的方法
在 Swift 中,操作字节数据主要依赖于以下几种数据结构和方法,比如 Data
、Array<UInt8>
和 UnsafePointer
系列。它们提供了许多灵活的方式来操作字节数据。以下是常见的操作方法及其用法,包括截取字节、编码、删除字节、统计等。
1. 基础字节数据类型
Data
:常用的字节数据容器,可以方便地进行字节操作。Array<UInt8>
:用数组表示的字节数据。UnsafePointer
系列:提供更底层的内存访问和字节操作。
2. 取从第几个字节到第几个字节的数据
-
使用
Data
的subdata(in:)
方法:let data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let range = 1..<4
let subData = data.subdata(in: range)
print(subData) // 输出 [2, 3, 4]
-
对于
Array<UInt8>
:let byteArray: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05]
let subArray = byteArray[1..<4]
print(subArray) // 输出 [2, 3, 4]
3. Base64 编码字节数据
-
使用
Data
的base64EncodedString()
方法:let data = Data([0x01, 0x02, 0x03, 0x04])
let base64String = data.base64EncodedString()
print(base64String) // 输出 "AQIDBA=="
-
如果你需要从
Array<UInt8>
进行 Base64 编码,首先将其转换为Data
:let byteArray: [UInt8] = [0x01, 0x02, 0x03, 0x04]
let data = Data(byteArray)
let base64String = data.base64EncodedString()
print(base64String) // 输出 "AQIDBA=="
4. 字节数据的移动
-
使用
replaceSubrange(_:with:)
方法可以在指定范围内替换数据,从而实现移动效果。例如,移动第 2-3 个字节到第 0 个字节开始:var data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let subrange = data.subdata(in: 2..<4)
data.replaceSubrange(0..<2, with: subrange)
print(data) // 输出 [3, 4, 3, 4, 5]
-
对于
Array<UInt8>
也可以使用类似的replaceSubrange
:var byteArray: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05]
let subArray = byteArray[2..<4]
byteArray.replaceSubrange(0..<2, with: subArray)
print(byteArray) // 输出 [3, 4, 3, 4, 5]
5. 删除指定范围的字节
-
使用
Data
的removeSubrange(_:)
方法:var data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
data.removeSubrange(1..<3)
print(data) // 输出 [1, 4, 5]
-
对于
Array<UInt8>
,也可以使用类似的removeSubrange
:var byteArray: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05]
byteArray.removeSubrange(1..<3)
print(byteArray) // 输出 [1, 4, 5]
6. 统计字节数量
-
对于
Data
类型,可以使用count
属性:let data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let count = data.count
print(count) // 输出 5
-
对于
Array<UInt8>
,也可以使用count
:let byteArray: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05]
let count = byteArray.count
print(count) // 输出 5
7. 替换指定范围内的字节
-
使用
Data
的replaceSubrange(_:with:)
方法:var data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let newData = Data([0xFF, 0xFE])
data.replaceSubrange(1..<3, with: newData)
print(data) // 输出 [1, 255, 254, 4, 5]
-
对于
Array<UInt8>
,同样可以使用replaceSubrange
:var byteArray: [UInt8] = [0x01, 0x02, 0x03, 0x04, 0x05]
let newArray: [UInt8] = [0xFF, 0xFE]
byteArray.replaceSubrange(1..<3, with: newArray)
print(byteArray) // 输出 [1, 255, 254, 4, 5]
8. 追加字节数据
-
使用
Data
的append
方法:var data = Data([0x01, 0x02])
data.append(Data([0x03, 0x04]))
print(data) // 输出 [1, 2, 3, 4]
-
对于
Array<UInt8>
,可以使用append(contentsOf:)
:var byteArray: [UInt8] = [0x01, 0x02]
byteArray.append(contentsOf: [0x03, 0x04])
print(byteArray) // 输出 [1, 2, 3, 4]
9. 将字节转换为字符串
- 使用
String(data:encoding:)
将Data
转换为字符串(需确保字节数据有效,比如 UTF-8 编码):let data = Data([0x48, 0x65, 0x6C, 0x6C, 0x6F])
if let string = String(data: data, encoding: .utf8) {
print(string) // 输出 "Hello"
}
10. 字节与十六进制表示的转换
-
-
- 将字节数据转换为十六进制字符串:
let data = Data([0x01, 0xFF, 0xAA])
let hexString = data.map {
String(format: "%02hhX", $0)
}.joined()
print(hexString) // 输出 "01FFAA"
- 将字节数据转换为十六进制字符串:
-
11. 字节数据与整形之间的转换
- 通过
withUnsafeBytes
从Data
中读取整数:let data = Data([0x01, 0x00, 0x00, 0x00]) // 假设这是 4 个字节表示的 1
let number = data.withUnsafeBytes { $0.load(as: UInt32.self) }
print(number) // 输出 1
总结
Swift 提供了很多处理字节数据的便利方法,尤其是通过 Data
和 Array<UInt8>
这两个主要数据结构。你可以通过 subdata
来截取数据,通过 base64EncodedString()
来编码,通过 replaceSubrange
和 removeSubrange
来移动或删除字节,操作起来非常灵活。
这些方法涵盖了绝大多数字节操作需求,具体的使用可以根据你的具体场景选择适合的数据结构和方法。