【问题标题】:Upload large file via URLSession通过 URLSession 上传大文件
【发布时间】:2016-11-22 00:00:50
【问题描述】:

所以我有一些代码用于在我的应用中上传文件,大致如下:

var mutableURLRequest = URLRequest(url: url)
var uploadData = try! Data(contentsOf: dataUrl)
session.uploadTask(with: mutableURLRequest, from: uploadData).resume()

除此之外还有更多内容,但这些都是相关部分。但是我注意到一些大型视频文件Data(contentsOf: dataUrl) 失败,因为文件太大而无法加载到内存中。我想对其进行重组,以便能够逐个将流传输到服务器,而无需将整个文件加载到内存中。

我已经从我的服务器中弄清楚了这一点,我唯一没有弄清楚的是如何从 URL 中的数据中获取 chunkSize 片段,而不将其放入数据对象中。我基本上想要这个结构:

let chunkSize = 1024 * 1024
let offset = 0
let chunk = //get data from dataUrl of size chunkSize offset by offset

//Upload each chunk and increment offset

NSInputStream 似乎很有希望能够做到这一点,但我无法弄清楚以这种方式从磁盘上的文件中提取字节的最小设置。我可以在上面使用什么代码来填写let chunk = 行来完成这样的任务?

【问题讨论】:

  • 你试过uploadTask(with:fromFile:)吗?从文件中流式传输而不是将整个内容加载到Data 中可能足够聪明。或者也许使用uploadTask(withStreamedRequest:)
  • 我猜这对我不起作用,因为我需要用其他一些 HTTP 垃圾来装饰每个块,以便我的服务器知道发生了什么。但是,无论它在幕后使用什么来做到这一点,这可能就是我需要的。
  • 我对@9​​87654330@ 进行了一些测试,可以确认它不会将整个文件加载到内存中!这最终成为我的完美解决方案。

标签: ios swift swift3 nsurlsession


【解决方案1】:

我有一个可行的解决方案,可能需要稍作调整,但似乎适用于我尝试过的大文件:

public func getNextChunk() -> Data?{
    if _inputStream == nil {
        _inputStream = InputStream(url: _url)
        _inputStream?.open()
    }
    var buffer = [UInt8](repeating: 0, count: CHUNK_SIZE)
    var len = _inputStream?.read(&buffer, maxLength: CHUNK_SIZE)
    if len == 0 {
        return nil
    }
    return Data(buffer)
}

我还在管理磁盘上文件分块的类的 deinit 上调用 _inputStream?.close()

【讨论】:

  • 酷!但是您将如何将这些和平一一发送到您的服务器?你会为每个块创建一个单独的请求还是有更聪明/有效的方法?
猜你喜欢
  • 2010-10-04
  • 1970-01-01
  • 1970-01-01
  • 2018-09-21
  • 1970-01-01
  • 2023-04-11
  • 2013-10-10
  • 2013-04-30
  • 1970-01-01
相关资源
最近更新 更多