ios - 如何在 iOS 中将大文件块明智地上传到 Azure blob 时减少内存使用量?
问题描述
当我们尝试在 Azure Blob 中上传大文件 (Chunk Wise) 时,我们会在 iOS 中遇到高内存使用问题。下面的代码已用于在 Azure Blob 中上传一个大文件(Chunk Wise)。
func uploadToBlob(_ url: URL) {
let blobClient = self.account?.getBlobClient()
let blobContainer = blobClient?.containerReference(fromName: Configure.shared.blobName!)
let blobBlock = blobContainer?.directoryReference(fromName: blobFolder).subdirectoryReference(fromName: directory).subdirectoryReference(fromName: subDirectory).blockBlobReference(fromName: Date().toUploadFormate+"_"+orgUrl.lastPathComponent)
let data = NSData(contentsOf: url)!
let length = data.length
let chunkSize = 4194304
var offset = 0
var blockList : [AZSBlockListItem] = []
func nextChunk() {
let thisChunkSize = length - offset > chunkSize ? chunkSize : length - offset
let chunk = Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: data.bytes+offset), count: thisChunkSize, deallocator: .none)
offset += thisChunkSize
let utf8str = UUID().uuidString.data(using: .utf8)
if let base64EncodedId = utf8str?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) {
blockList.append(AZSBlockListItem(blockID: base64EncodedId, blockListMode: .uncommitted))
func uploadBlockList() {
blobBlock?.uploadBlockList(from: blockList, completionHandler: { (bError) in
guard bError == nil else {
print(bError!)
uploadBlockList()
return
}
})
}
func uploadBlock() {
blobBlock?.uploadBlock(from: chunk, blockID: base64EncodedId, completionHandler: { (error) in
guard error == nil else {
uploadBlock()
return
}
guard offset >= length else {
nextChunk()
return
}
uploadBlockList()
})
}
uploadBlock()
}
}
nextChunk()
}
这是显示高内存使用问题的图像。
解决方案
试试@Cy-4AH 提到的这段代码
@IBAction func onReadStream(_ sender: UIButton) {
guard videoURL != nil else { return }
guard let inputStream = InputStream(url: videoURL!) else { return }
do {
try readingInputStream(reading: inputStream)
} catch {
print(error)
}
}
func readingInputStream(reading input: InputStream) throws {
input.open()
defer {
input.close()
}
let bufferSize = 1024
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: bufferSize)
defer {
buffer.deallocate()
}
while input.hasBytesAvailable {
let read = input.read(buffer, maxLength: bufferSize)
if read < 0 {
throw input.streamError!
} else if read == 0 {
break
}
let data = Data(bytes: buffer, count: read)
print(data)
// Here you can upload data to server
}
}
推荐阅读
- python-3.x - 更改时要归档的 Python 文本
- java - Spring Data - 数据库中的项目,但 entityManager 找不到
- php - PHP 清理 PHP PDO 连接中使用的字符串
- asp.net - 将 X509Certificate2 与 Windows 证书存储、HSM 和 Azure Key Vault 一起使用
- javascript - for循环中的Javascript SetInterval
- perforce - 从 p4 更改命令中获取日期
- flutter - Flutter Firebase 身份验证:启动延迟
- ios - UITextField 上下文菜单(剪切、粘贴等)未显示
- c++ - 'std::system_error',生产者消费者 C++ 并发
- c++ - 用户定义类的运算符重载在 C++ 中不起作用