Flutter dio 文件上传下载

Dio 是Flutter 网络请求的Pub包 Dio除了常用的get post 还可以文件下载 上传等操作
关于文件分片上传 或者文件下载

用到的pub 包

  #文件选择
  file_selector: ^0.8.2
  file_selector_windows: ^0.8.2
  file_selector_macos: ^0.0.4
  file_selector_linux: ^0.0.2
  file_selector_web: ^0.8.1
   #网络请求
  dio: ^4.0.0

文件分片上传

  • 获取本地文件信息[路径 名称 大小 等]
  • 文件分片
  • 上传分片到服务器
  • 结束

获取本地文件信息

 _openLocalSingleFile() async {
    try {
      final xTypeGroup =
      XTypeGroup(label: '资源类型(jpg,png,mp4,gif)', extensions: [
        'jpg',
        'jpeg',
        'png',
        'gif',
        'mp4',
      ]);
      final XFile = await openFiles(acceptedTypeGroups: [xTypeGroup]);
      List items = [];
      for (var e in XFile) {
        items.add(LocalFile(
          e.path,
          mineType: e.mimeType,
          fileType: e.name.contains('mp4') ? 1 : 0,
          name: e.name,
          length: 0,
        ));
      }
      _mainController.addSelLocalFilesToUpload(items);
    } catch (e) {}
  }
}

文件分片&上传分片到服务器

/// count 当前上传进度
/// total 上传总长度
/// type 转码状态 
typedef UploadProgressCallBack = Function(int count, int total, {int? type});

  ///文件分片上传
  ///url 文件上传地址
  ///localFilePath 本地文件地址
  ///progressCallBack 上传进度
  ///videoConvertModel 视频信息
  static Future uploadSliceFile(String url, String localFilePath,
      UploadProgressCallBack? progressCallBack,
      {AddVideoConvertModel? videoConvertModel}) async {
    try {
      final String fileUrl = await Global.getFileUrl();
      final String token = await Global.getUserToken();
      var xFile = XFile(localFilePath);
      int startOffset = 0;
      bool upload = true;
      var xRead = await xFile.readAsBytes(); //读取字节流
      List bit = xRead.toList();
      var length = bit.length;
      while (upload) { //分片上传
        List bitU = [];
        int isLast = 0;
        if (startOffset == 0) {
          if (length <= 1000 * 1024) {
            bitU = bit;
            isLast = 1;
          } else {
            bitU = bit.sublist(startOffset, startOffset + (1000 * 1024));
          }
        } else {
          if ((length - startOffset) <= 1000 * 1024) {
            isLast = 1;
            bitU = bit.sublist(startOffset);
          } else {
            bitU = bit.sublist(startOffset, startOffset + (1000 * 1024));
          }
        }
        ///上传文件分片
        var fileResponseModel =
            await _upload(fileUrl, token, url, bitU, startOffset, isLast,
                (count, t, {int? type}) {
          if (progressCallBack != null) {
            progressCallBack(count + startOffset, length, type: type);
          }
        });
        if (fileResponseModel != null) {
          startOffset = fileResponseModel.startOffset ?? 0;
          upload = !(fileResponseModel.isSuccess == true && isLast == 1);
        }
      }
      ///视频转码=============
      if (Extension.fileType(url) == 1 && videoConvertModel != null) {
        var result =
            await _postAddVideoConvertTask(fileUrl, token, videoConvertModel) ??
                false;
        if (result == true) {
          bool r = true;
          while (r) {
            var result = await _getVideoConvertStatus(
                fileUrl, token, videoConvertModel.videoId);
            if (result == 1) {
              //转码成功
              r = false;
              print('转码成功==============');
              if (progressCallBack != null) {
                progressCallBack(0, 0, type: 1);
              }
            } else {
              print('${result == 3 ? '转码中' : ''}');
              if (progressCallBack != null) {
                progressCallBack(0, 0, type: 3);
              }
            }
            await Future.delayed(Duration(seconds: 5));
          }
          return true;
        } else {
          return false;
        }
      }
      return true;
    } catch (e) {
      print(e);
    }
    return false;
  }
  
  static Future _upload(
      String fileUrl,
      String token,
      String url,
      List bit,
      int offset,
      int isLast,
      UploadProgressCallBack? progressCallBack) async {
    var fromFile = await MultipartFile.fromBytes(bit, filename: '');
    final Dio dio = Dio(BaseOptions(
        baseUrl: fileUrl + "/",
        sendTimeout: timeOut,
        method: "POST",
        connectTimeout: timeOut,
        headers: {
          'Auth': token,
          'Charset': 'UtF-8',
          'Connection': 'Keep-Alive',
          'Content-Type': 'multipart/form-data;boundary=----------'
        }));
    var formData = FormData.fromMap({'file': fromFile});
    final r = await dio.post('api/FileUpload/UploadCarveFile',
        queryParameters: {
          'relativeServerName': url,
          'offset': offset,
          'isLast': isLast,
          'isRetainOrigianl':
              Extension.fileType(url) == 0 || Extension.fileType(url) == 1
                  ? 1
                  : 0
        },
        data: formData, onSendProgress: (int count, int total) {
      var callBack = progressCallBack ?? (int count, int total, {int? type}) {};
      callBack(count, total, type: 0);
    });
    var httpResultModelTwo =
        HttpResultModelTwo.fromJson(json.decode(r.data.toString()));
    if (httpResultModelTwo.responseStatus == 1) {
      return FileResponseModel.fromJson(httpResultModelTwo.data!);
    }
    return null;
  }

文件下载

  ///下载文件到本地
  ///urlPath 文件Url
  ///savePath 本地保存位置
  ///downloadProgressCallBack 下载文件回调
  static Future downloadFile(String urlPath, String savePath,
      {DownloadProgressCallBack? downloadProgressCallBack}) async {
    Dio dio = Dio();
    return await dio.download(urlPath, savePath,
        onReceiveProgress: downloadProgressCallBack);
  }
  
  
/// count 当前下载进度
/// total 下载总长度
typedef DownloadProgressCallBack = Function(int count, int total);

你可能感兴趣的:(Flutter,flutter,android)