在 Swift 3 中将数据拆分为块

Posted

技术标签:

【中文标题】在 Swift 3 中将数据拆分为块【英文标题】:Splitting Data into chunks in Swift 3 【发布时间】:2017-07-23 21:24:02 【问题描述】:

我需要通过网络发送从照片库读取的图像 - 以 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' 常量

这是正确的,因为我真的不想更改图像数据。我只想一次发送一大块。

有没有更好的方法来做到这一点?

【问题讨论】:

标记解决方案时会很好。谢谢 【参考方案1】:

你好!

我需要相同的行为并想出了这个解决方案。您指出了正确的错误,解决方案只是使用 UnsafePointer 地址创建 UnsafeMutableRawPointer。这是我找到的最快的解决方案。

另一件事是在创建块时将偏移量添加到 mutRawPointer 的基地址。

2MB 块中的 50MB 数据大约需要 0.009578 秒

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
        
    

【讨论】:

这适用于较小的文件,但如果您想拆分一个 4GB 的文件,则必须将其全部加载到内存中,这在大多数情况下可能不起作用。 有更好的解决方案吗?【参考方案2】:

Data(bytesNoCopy: ... 初始化器需要一个可变指针。将您的代码更改为以下内容以使其工作:

imageData.withUnsafeMutableBytes  (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in
    // your code

【讨论】:

以上是关于在 Swift 3 中将数据拆分为块的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中将字符串拆分为数组?

将 jsonarray 拆分为块数组到另一个数组中

关于如何在 Swift 中将字符串拆分为所需字符串数组的问题

将数组拆分为块

将 QList 拆分为块、指针或引用?

如何在 Swift 3 中将 NSData 转换为数据?