html大文件占用内存,[Flutter] 大文件上传之随传随处理(避免占用大量内存)

今天碰到一个上传较大的视频文件到S3引发闪退的问题。经查此问题产生的原因是内存溢出,连个闪退日志都没有。

这个上传使用的是第三方的插件,我是用 uploadFileStream 来上传文件的,查看其实现代码,它使用的是http插件的 http.StreamedRequest, 它会把文件分块读出来,添加分块签名,再使用 request.sink.add(xxx) 加入缓冲区, 最后调用 request.send() 来完成发送。

这样问题就来了,它会把整个文件外加签名信息都放到缓冲区,意味着文件越大,也就占用更多的内存,最终导致崩溃的发生。

由于需要对文件进行签名处理,不能直接使用 dio 插件文件上传方式(说不定dio也会有同样的问题,还没来得及细品)。http 插件也没有提供边读边处理边发送的方法,问题限入卡顿状态,在网上搜索半天也没有找到一个解决方案,最后想想,能不能直接用最基础的 HttpClient 来解决呢?

因为平常主要用dio和http这两个插件,没有用过HttpClient,没有认真研究过它。这个时候想起来它,就马上细品起来,最终真的找到的解决方案。还真是越低级的封装,关键时候越能解决问题。

下面给出使用 HttpClient 解决上面问题的关键代码:

//初始化一个Http客户端,并加入自定义Header

var req =await HttpClient().putUrl(uri);

headers.forEach((key, value) {

req.headers.add(key, value);

});//读文件

var s =await file.open();var x = 0;var size =file.lengthSync();var chunkSize = 65536;while (x = chunkSize ? chunkSize : size -x;

val=s.readSync(_len).toList();

x= x +_len;//处理数据块

val =proc(val);//加入http发送缓冲区

req.add(val);//立即发送并清空缓冲区

await req.flush();

}

await s.close();//文件发送完成

await req.close();//获取返回数据

final response =await req.done;//其它处理逻辑

print("response statusCode: ${resp.statusCode}");

经测试,用上面方法上传大文件,内存占用平稳,最后真机测试,也没有再闪退。

原文:https://www.cnblogs.com/yangyxd/p/13094925.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值