flutter Web实现大文件上传

flutter web在实现大文件文件上传时受浏览器限制内存分配限制,需要用流的方式读入文件上传。

使用三方库 file_picker 进行文件选择

FilePickerResult? result = await FilePicker.platform.pickFiles(
      allowMultiple: true,
      withData: false,
      withReadStream: true,
    );
if(result == null){
    return;
}

这里withData一定要设置为false,表示不返回文件数据。withReadStream一定设置为true,表示以流的方式读入数据。如果withData设置为true,会直接将选择文件数据一次性访问,如果文件稍微大一点浏览器就会报内存分配失败。

上传文件

使用http package 来实现文件上传,在pubspec.yaml 文件中引入http

dependencies:
  http: ^1.2.1

或者运行如下命令

$ flutter pub add http

文件上传代码

import 'package:http/http.dart' as http;

for(var f in result.files) async{
    //上传文件URL
    String apiurl = "https://xxx.xxx.xxx/upload";
    String response = await uploadFile(apiurl, f);
    print(response);
}

uploadFile(String uploadurl, PlatformFile f) async{

    final request = http.MultipartRequest("POST", Uri.parse(uploadurl));
    //设置post请求Headers,比如认证信息
    request.headers['authtoken'] = “xxxxx";

    //将文件流参数传递给MultipartFile
    request.files
.add(http.MultipartFile("file", f.readstream!, f.size, filename: f.name));
    //调用send方法发送post请求
    var resp = await request.send();

    //等待上传完成返回结果
    String result = await resp.stream.bytesToString();
    return result;
}

Leave a Comment

Your email address will not be published. Required fields are marked *

7 thoughts on “flutter Web实现大文件上传”

  1. 可以在MultipartRequest中监听上传进度
    final request = http.MultipartRequest(
    “POST”,
    Uri.parse(uploadurl),
    onProgress: (int bytes, int total) {
    final progress = bytes / total;
    print(‘progress: $progress ($bytes/$total)’);
    },
    );

    1. 这个进度是发送数据的进度,而不是真是上传的进度,结果就是现实上传已经完成,其实真是的上传还没有结束。

  2. 可以用Dio来实现上传监控:
    dio.post(url,
    data: formData, options: Options(headers: header),
    onSendProgress: (int count, int total)
    onSendProgress里面的count就是已上传的大小,total就是文件总大小。