将数据分成 Swift 3 中的块
Splitting Data into chunks in Swift 3
我需要通过网络以 5MB 的块发送从照片库中读取的图像。
我使用以下方法从库中读取图像:PHImageManager.requestImageData(for:options:resultHandler:)
并得到一个 Data
对象。然后我想有效地将数据分成块(不复制内存)。最好的方法是什么?
这是我目前拥有的:
imageData.withUnsafeBytes { (unsafePointer: UnsafePointer<UInt8>) -> Void in
let totalSize = data.endIndex
var offset = 0
while offset < totalSize {
let chunkSize = offset + uploadChunkSize > totalSize ? totalSize - offset : uploadChunkSize
let chunk = Data(bytesNoCopy: unsafePointer, count: chunkSize, deallocator: Data.Deallocator.none)
// send the chunk...
offset += chunkSize
}
}
但是我在编译时得到这个错误:
无法将类型 'UnsafePointer' 的值转换为预期的参数类型 'UnsafeMutableRawPointer'
如果我使用 mutableBytes:
data.withUnsafeMutableBytes { (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in... }
然后我得到编译时错误:
不能在不可变值上使用可变成员:'data' 是一个 'let' 常量
这是正确的,因为我真的不想更改图像数据。我一次只想发送其中的一部分。
有更好的方法吗?
Data(bytesNoCopy: ...
初始化程序需要一个可变指针。将您的代码更改为以下内容以使其工作:
imageData.withUnsafeMutableBytes { (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in
// your code
}
您好!
我需要相同的行为并想出了这个解决方案。您指出了正确的错误,解决方案只是使用 UnsafePointer 地址创建 UnsafeMutableRawPointer。这是我找到的最快的解决方案。
另一件事是在创建块时将偏移量添加到 mutRawPointer 的基地址。
2MB 块中的 50MB 数据大约需要 0.009578s
func createChunks(forData: Data) {
imageData.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in
let mutRawPointer = UnsafeMutableRawPointer(mutating: u8Ptr)
let uploadChunkSize = 2097152
let totalSize = imageData.count
var offset = 0
while offset < totalSize {
let chunkSize = offset + uploadChunkSize > totalSize ? totalSize - offset : uploadChunkSize
let chunk = Data(bytesNoCopy: mutRawPointer+offset, count: chunkSize, deallocator: Data.Deallocator.none)
offset += chunkSize
}
}
}
我需要通过网络以 5MB 的块发送从照片库中读取的图像。
我使用以下方法从库中读取图像:PHImageManager.requestImageData(for:options:resultHandler:)
并得到一个 Data
对象。然后我想有效地将数据分成块(不复制内存)。最好的方法是什么?
这是我目前拥有的:
imageData.withUnsafeBytes { (unsafePointer: UnsafePointer<UInt8>) -> Void in
let totalSize = data.endIndex
var offset = 0
while offset < totalSize {
let chunkSize = offset + uploadChunkSize > totalSize ? totalSize - offset : uploadChunkSize
let chunk = Data(bytesNoCopy: unsafePointer, count: chunkSize, deallocator: Data.Deallocator.none)
// send the chunk...
offset += chunkSize
}
}
但是我在编译时得到这个错误:
无法将类型 'UnsafePointer' 的值转换为预期的参数类型 'UnsafeMutableRawPointer'
如果我使用 mutableBytes:
data.withUnsafeMutableBytes { (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in... }
然后我得到编译时错误:
不能在不可变值上使用可变成员:'data' 是一个 'let' 常量
这是正确的,因为我真的不想更改图像数据。我一次只想发送其中的一部分。
有更好的方法吗?
Data(bytesNoCopy: ...
初始化程序需要一个可变指针。将您的代码更改为以下内容以使其工作:
imageData.withUnsafeMutableBytes { (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in
// your code
}
您好!
我需要相同的行为并想出了这个解决方案。您指出了正确的错误,解决方案只是使用 UnsafePointer 地址创建 UnsafeMutableRawPointer。这是我找到的最快的解决方案。
另一件事是在创建块时将偏移量添加到 mutRawPointer 的基地址。
2MB 块中的 50MB 数据大约需要 0.009578s
func createChunks(forData: Data) {
imageData.withUnsafeBytes { (u8Ptr: UnsafePointer<UInt8>) in
let mutRawPointer = UnsafeMutableRawPointer(mutating: u8Ptr)
let uploadChunkSize = 2097152
let totalSize = imageData.count
var offset = 0
while offset < totalSize {
let chunkSize = offset + uploadChunkSize > totalSize ? totalSize - offset : uploadChunkSize
let chunk = Data(bytesNoCopy: mutRawPointer+offset, count: chunkSize, deallocator: Data.Deallocator.none)
offset += chunkSize
}
}
}