1、读取和初始化
Data(contentsOf:)
从指定的 URL 读取数据并初始化一个 Data 对象。
常用于从文件或网络 URL 读取数据。
if let url = URL(string: "https://example.com/image.jpg") {
do {
let data = try Data(contentsOf: url)
// 使用 data,例如加载到 UIImage
} catch {
print("读取失败: \(error)")
}
}
声明
init(contentsOf url: URL, options: Data.ReadingOptions = []) throws
options: Data.ReadingOptions
读取选项:
.mappedIfSafe:尽可能使用内存映射文件。
.uncached:避免缓存。
.alwaysMapped:强制使用内存映射文件(可能增加性能,但资源使用更多)。
Data(repeating:count:)
创建一个包含重复字节的 Data 对象。
可以用来创建指定大小的空白数据对象,或填充特定的字节值。
// 创建一个长度为 10,所有字节为 0 的 Data 对象
let data = Data(repeating: 0, count: 10)
print(data) // 输出类似 <00000000000000000000>
Data(base64Encoded:)
从 Base64 编码的字符串或 Data 中解码数据。
在处理 Base64 编码的文本数据时使用,比如处理图片、文件等编码后的数据。
let base64String = "SGVsbG8gV29ybGQh" // "Hello World!" 的 Base64 编码
if let data = Data(base64Encoded: base64String) {
print("解码成功: \(data)")
} else {
print("解码失败")
}
Data(base64Encoded:options:)
使用选项从 Base64 编码的字符串解码数据。
处理有格式要求的 Base64 数据,options 参数提供更灵活的控制,比如允许忽略空白字符。
let base64String = "SGVsbG8gIFdvcmxkIQ==" // 带空格
if let data = Data(base64Encoded: base64String, options: .ignoreUnknownCharacters) {
print("解码成功: \(data)")
} else {
print("解码失败")
}
选项:
.ignoreUnknownCharacters: 忽略字符串中非 Base64 字符。
2、数据操作
append(_:):
将一个 Data 对象的内容附加到另一个 Data 对象的末尾。
var data1 = Data([0x01, 0x02, 0x03])
let data2 = Data([0x04, 0x05])
data1.append(data2)
print(data1) // 输出: [0x01, 0x02, 0x03, 0x04, 0x05]
subdata(in:)
从 Data 中提取指定范围内的字节并返回一个新的 Data 对象。
let data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let subData = data.subdata(in: 1..<3)
print(subData) // 输出: [0x02, 0x03]
replaceSubrange(_:with:)
用新的数据替换 Data 对象的某个范围内的字节。
var data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let replacementData = Data([0xAA, 0xBB])
data.replaceSubrange(1..<3, with: replacementData)
print(data) // 输出: [0x01, 0xAA, 0xBB, 0x04, 0x05]
dropFirst(_:) / dropLast(_:)
删除前 n 个或后 n 个字节,返回新的 Data 对象(不会修改原数据)。
let data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let droppedFirstTwo = data.dropFirst(2)
let droppedLastTwo = data.dropLast(2)
print(droppedFirstTwo) // 输出: [0x03, 0x04, 0x05]
print(droppedLastTwo) // 输出: [0x01, 0x02, 0x03]
prefix(_:) / suffix(_:)
获取 Data 对象前 n 个或后 n 个字节,返回一个新的 Data 对象。
let data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
let prefixData = data.prefix(2)
let suffixData = data.suffix(2)
print(prefixData) // 输出: [0x01, 0x02]
print(suffixData) // 输出: [0x04, 0x05]
removeSubrange(_:)
从 Data 对象中删除指定范围的字节。
var data = Data([0x01, 0x02, 0x03, 0x04, 0x05])
data.removeSubrange(1..<3)
print(data) // 输出: [0x01, 0x04, 0x05]
3、编码和解码
base64EncodedString()
将 Data 编码为 Base64 格式的字符串,适合用于网络传输或存储文本数据。
let data = "Hello, World!".data(using: .utf8)!
let base64String = data.base64EncodedString()
print(base64String) // 输出: "SGVsbG8sIFdvcmxkIQ=="
base64EncodedData()
将 Data 对象编码为 Base64 格式的数据类型 Data。这种形式可以在不转换为字符串的情况下直接处理 Base64 编码的数据。
let data = "Hello, World!".data(using: .utf8)!
let base64Data = data.base64EncodedData()
print(base64Data) // 输出: <53475673 62673073 3d3d>
jsonObject(with:)
jsonObject(with:) 方法用于将 JSON 格式的 Data 解码为 Swift 对象,如字典 (Dictionary) 或数组 (Array)。
try JSONSerialization.jsonObject(with:) 会尝试将 Data 转换为 Any 类型的对象。
如果 JSON 是字典形式,则返回 [String: Any] 类型。
如果 JSON 是数组形式,则返回 [Any] 类型。。
let jsonData = """
{
"name": "John",
"age": 30,
"isStudent": false
}
""".data(using: .utf8)!
do {
if let jsonObject = try JSONSerialization.jsonObject(with: jsonData) as? [String: Any] {
print(jsonObject) // 输出: ["name": "John", "age": 30, "isStudent": false]
if let name = jsonObject["name"] as? String {
print("Name: \(name)") // 输出: Name: John
}
}
} catch {
print("JSON 解码失败: \(error)")
}
4、比较和验证
starts(with:)
检查 Data 是否以指定的字节序列开头。
let data = "Hello, World!".data(using: .utf8)!
let prefix = "Hello".data(using: .utf8)!
if data.starts(with: prefix) {
print("Data 以 'Hello' 开头") // 输出: Data 以 'Hello' 开头
} else {
print("Data 不以 'Hello' 开头")
}
elementsEqual(_:)
检查 Data 是否与另一个 Data 或字节序列完全相等。
let data1 = "Hello, World!".data(using: .utf8)!
let data2 = "Hello, World!".data(using: .utf8)!
if data1.elementsEqual(data2) {
print("两个 Data 对象相等") // 输出: 两个 Data 对象相等
} else {
print("两个 Data 对象不相等")
}
contains(_:)
检查 Data 是否包含指定的字节。例如,可以查看一个 Data 对象中是否包含某个 ASCII 字节。
let data = "Hello, World!".data(using: .utf8)!
let byte: UInt8 = 87 // ASCII 码 87 表示 'W'
if data.contains(byte) {
print("Data 包含字节 'W'") // 输出: Data 包含字节 'W'
} else {
print("Data 不包含字节 'W'")
}
count
返回 Data 对象中的字节数。这个属性直接访问即可,通常用于检查数据大小。
let data = "Hello, World!".data(using: .utf8)!
print("字节数: \(data.count)") // 输出: 字节数: 13
5.、哈希和加密
hash(into:)
hash(into:) 通过对数据进行哈希编码,将结果传递给 Hasher 对象。该方法通常在自定义类型中使用,并实现 Hashable 协议,以便支持哈希相关操作。
struct MyDataWrapper: Hashable {
var data: Data
func hash(into hasher: inout Hasher) {
hasher.combine(data)
}
}
// 示例
let data1 = "Hello, World!".data(using: .utf8)!
let wrapper1 = MyDataWrapper(data: data1)
var hasher = Hasher()
wrapper1.hash(into: &hasher)
let hashValue = hasher.finalize()
print("哈希值:\(hashValue)")
description
description 属性是 Data 的十六进制字符串表示,默认情况下用于显示 Data 对象的内容,主要用于调试目的。
let data = "Hello, World!".data(using: .utf8)!
print("Data 的十六进制表示: \(data.description)")
在调试输出时,description 会将 Data 以十六进制格式显示,例如 “Hello” 转换后的 Data 对象描述可能是:
Data 的十六进制表示: <48656c6c 6f>
6、写入数据
write(to:options:)
将数据写入指定文件路径。
func write(to url: URL, options: Data.WritingOptions = []) throws
url: URL
要写入的文件路径,通常是本地文件系统的路径(file:// 格式)。
options: Data.WritingOptions
写入选项,可选值包括:
.atomic:原子性写入,确保数据完整。如果失败,原始文件不会被破坏。
.withoutOverwriting:防止覆盖已有文件。
.completeFileProtection:启用文件保护(在支持的平台上)。
try data.write(to: url, options: [.atomic, .completeFileProtection])
options选项为原子性写入,并启用文件保护。