我对Swift相当陌生,对NIO也很陌生。
我将Swift代码添加到一个需要向上/向下加载大量数据(GBs)到AWS的大型项目中。为此,我导入了GitHub项目佐藤,该项目严重依赖NIO。
大多数发送/接收数据的方法都是通过ByteBuffer结构完成的。我的应用程序已经有了要上传到Foundation Data对象中的数据。我很难找到让这些Data对象进入NIO的最佳方法。
在(2.26.0)的文档中,它声明
受支持的类型:可以从ByteBuffer中读取/写入多种类型。..。例如,ByteBuffer支持以下类型(并非详尽无遗的列表):
然而,最新的快速零包不支持基金会ByteBuffer Data对象.相反,它支持DispatchData对象,而这些对象又似乎没有与Data对象的互操作性。
我想避免的是复制每个数据块(每次100 MB ),以便在Data和DispatchData类型之间进行转换。
所以..。
现在我的想法是
DispatchData对象支持的Data子类。ByteBuffer对象中的原始字节数组的非复制初始化器创建的DispatchData初始化Data结构,以及一个自定义释放符,它只保留Data对象,直到ByteBuffer和DispatchData对象被销毁。我希望有任何想法,经验或建议(特别是如果是选项1)。
发布于 2021-03-08 18:37:44
您需要import NIOFoundationCompat来获得任何使用Foundation数据类型(如Data (或JSONDecoder/JSONEncoder) )的NIO方法。NIOFoundationCompat只是swift-nio包的另一个模块,因此不需要另一个依赖项。
但是要明确的是,在引擎盖下,总是会有副本,但是你可能不需要担心它们,拷贝在今天的CPU上是非常快的。如果您绝对希望避免复制,则需要立即创建ByteBuffer。为了帮助您,您可能需要添加要通过网络发送的数据来自何处。
发布于 2021-04-15 09:49:59
如果您关心内存的使用,并且正在上传大型缓冲区,也许您应该使用AWSPayload.stream。这允许您将小ByteBuffers流到AWS。下面是以16k块将Data流到S3的示例
func uploadData( _ data: Data) -> EventLoopFuture<S3.PutObjectOutput> {
var index = 0
let payload = AWSPayload.stream { eventLoop in
let maxChunkSize = 16*1024
let size = min(maxChunkSize, data.count - index)
// are we done yet
if size == 0 {
return eventLoop.makeSucceededFuture(.end)
} else {
// create bytebuffer and return
let byteBuffer = ByteBufferAllocator().buffer(data: data[index..<(index+size)])
index += size
return eventLoop.makeSucceededFuture(.byteBuffer(byteBuffer))
}
}
let putRequest = S3.PutObjectRequest(body: payload, bucket: name, key: "tempfile")
return s3.putObject(putRequest)
}https://stackoverflow.com/questions/66534661
复制相似问题