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<LocalFile> 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<bool> 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<int> bit = xRead.toList();
      var length = bit.length;
      while (upload) { //分片上传
        List<int> 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<FileResponseModel?> _upload(
      String fileUrl,
      String token,
      String url,
      List<int> 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<String>('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<Response> 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);
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flutter中使用Dio库进行文件上传可以通过以下步骤实现: 首先,确保已经在项目的`pubspec.yaml`文件中添加了Dio库的依赖: ```yaml dependencies: dio: ^4.0.0 ``` 然后,在需要上传文件的地方引入Dio库: ```dart import 'package:dio/dio.dart'; ``` 接下来,创建一个Dio的实例并配置它: ```dart var dio = Dio(); ``` 然后,使用Dio的`FormData`类来创建一个表单数据对象,并添加需要上传的文件: ```dart FormData formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(file.path, filename: 'upload.jpg'), }); ``` 这里的`file`是一个`File`对象,表示需要上传的文件。 最后,使用Dio的`post`方法发送请求,并将表单数据作为参数传递给它: ```dart Response response = await dio.post( 'https://example.com/upload', data: formData, ); ``` 这里的`https://example.com/upload`是上传文件的接口地址,你需要替换为实际的地址。 完整的示例代码如下: ```dart import 'dart:io'; import 'package:dio/dio.dart'; void main() async { var dio = Dio(); File file = File('path/to/file.jpg'); FormData formData = FormData.fromMap({ 'file': await MultipartFile.fromFile(file.path, filename: 'upload.jpg'), }); Response response = await dio.post( 'https://example.com/upload', data: formData, ); print(response.data); } ``` 通过以上步骤,你就可以使用Dio库在Flutter上传文件了。记得根据实际情况修改代码中的文件路径和上传接口地址。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值