在Swift 3中将数据拆分为块

GK1*_*100 5 upload chunks swift

我需要通过电线发送从照片库中读取的图像 - 大小为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
        }
    }
Run Code Online (Sandbox Code Playgroud)

但是我在编译时遇到这个错误:

无法将'UnsafePointer'类型的值转换为预期的参数类型'UnsafeMutableRawPointer'

如果我使用mutableBytes:

data.withUnsafeMutableBytes { (unsafePointer: UnsafeMutablePointer<UInt8>) -> Void in... }
Run Code Online (Sandbox Code Playgroud)

然后我得到编译时错误:

不能在不可变值上使用变异成员:'data'是'let'常量

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

有一个更好的方法吗?

Joh*_*ohn 10

嗨,您好!

我需要相同的行为并提出这个解决方案.您指出错误是正确的,解决方案只是使用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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这适用于较小的文件,但如果您想拆分 4GB 的文件,则必须将其全部加载到内存中,这在大多数情况下可能不起作用。 (2认同)