簡體   English   中英

Flutter 上傳帶進度條的大文件。 App和Web都支持

[英]Flutter upload large file with progress bar. App and Web both support

我遇到上傳大文件的問題。 當從應用程序上傳文件工作正常但 web 掛起時,為 Web 和應用程序(本機)編譯了 flutter 應用程序。 如何將大文件作為 stream 請求發送。

我是 flutter 的新手,正在開發當前現有的應用程序,該應用程序具有上傳大型教程視頻文件和 PDF 文件的功能。 要求是在上傳文件的過程中顯示進度條,目前應用程序有我使用dio但它掛在 web 版本中,而不是文件不上傳操作失敗。

  • 文件大小大約 400MB 到 700MB

目前使用以下軟件包

dependencies:
  http: ^0.12.2
  dio: ^3.0.10

你能幫我解決這個問題嗎?

我正在嘗試使用以下代碼來實現,但有些代碼無法正常工作。 https://github.com/salk52/Flutter-File-Upload-Download

它拋出類似“內存緩沖區分配失敗”的錯誤,由於其他 package 干擾,我無法更新dio或 http 的版本。 不知何故,我必須使用httpclientdio來實現它。 我無法更新 package 的版本,因為它弄亂了其他 package 依賴項。

樣品參考。 代碼如下:文件大小約為 500 MB 到 700MB

對於參考。 以下代碼中使用的代碼。

Dio package 示例:

#Dio example start

  Future<NormalResponse> addSubjectMaterial(
      {GetSubjectMaterial objSubMat,
      bool isDelete,
      PlatformFile objfile,
      Function sendProgress,
      Function receiveProgress,
      dio.CancelToken cancelToken}) async {
    NormalResponse objRes = NormalResponse();
    try {
      print(objSubMat.objMaterial.subjectId);
      dio.FormData formData = dio.FormData();
      formData.fields.add(MapEntry("ObjSubMat", json.encode(objSubMat)));
      formData.fields.add(MapEntry("IsDelete", isDelete.toString()));
      formData.fields
          .add(MapEntry("ClassesId", AppConstants.classesId().toString()));
      if (objfile != null) {
        formData.files.add(
            MapEntry("objfile", await getMultipartFile(objfile, "objfile")));
      }
      var resp = await dio.Dio().post(
        AppConstants.addUpdateSubjectMaterial,
        data: formData,
        options: requestConfig,
        cancelToken: cancelToken,
        onSendProgress: sendProgress,
        onReceiveProgress: receiveProgress,
      );

      // String respStr = resp.toString();
      // objRes = NormalResponse.fromJson(json.decode(respStr));
      objRes = NormalResponse.fromJson(resp.data);
    } catch (err) {
      objRes.err = err.toString();
      objRes.isSuccess = false;
      objRes.newId = -1;
      sendProgress = null;
      receiveProgress = null;
    }
    return objRes;
  }

#Dio example end

#httpclient example code is there any solution with progress bar in this sample code.

   Future<NormalResponse> addUpdateSubjectMaterialHttp(
       {GetSubjectMaterial objSubMat,
       bool isDelete,
       PlatformFile objfile,
       Function sendProgress,
       Function receiveProgress,
       dio.CancelToken cancelToken}) async {
     NormalResponse objRes = NormalResponse();
     try {
       var req = http.MultipartRequest(
         "POST",
         Uri.parse(AppConstants.addUpdateSubjectMaterial),
       );
       req.headers.addAll({
         'Content-type': 'application/json',
         'Accept': 'application/json',
       });
       req.fields['ObjSubMat'] = json.encode(objSubMat);
       req.fields['IsDelete'] = isDelete.toString();
       req.fields['ClassesId'] = AppConstants.classesId().toString();

       if (objfile != null) {
         req.files.add(http.MultipartFile(
             "objFile", objfile.readStream, objfile.size,
             filename: objfile.name));
       }

       var resp = await req.send();
       String result = await resp.stream.bytesToString();
       objRes = NormalResponse.fromJson(json.decode(result));
       print(objRes.isSuccess);
       print(objRes.err);
       print("Here done");
     } catch (err) {
       print(err);
       throw err;
     }
     return objRes;
   }
   
#httpclient


Http package example:

#example start

  Future<NormalResponse> addSubjectMaterial(
      {GetSubjectMaterial objSubMat,
      bool isDelete,
      PlatformFile objfile,
      Function sendProgress,
      Function receiveProgress,
      dio.CancelToken cancelToken}) async {
    NormalResponse objRes = NormalResponse();
    try {
      print(objSubMat.objMaterial.subjectId);
      dio.FormData formData = dio.FormData();
      formData.fields.add(MapEntry("ObjSubMat", json.encode(objSubMat)));
      formData.fields.add(MapEntry("IsDelete", isDelete.toString()));
      formData.fields
          .add(MapEntry("ClassesId", AppConstants.classesId().toString()));
      if (objfile != null) {
        formData.files.add(
            MapEntry("objfile", await getMultipartFile(objfile, "objfile")));
      }
      var resp = await dio.Dio().post(
        AppConstants.addUpdateSubjectMaterial,
        data: formData,
        options: requestConfig,
        cancelToken: cancelToken,
        onSendProgress: sendProgress,
        onReceiveProgress: receiveProgress,
      );

      // String respStr = resp.toString();
      // objRes = NormalResponse.fromJson(json.decode(respStr));
      objRes = NormalResponse.fromJson(resp.data);
    } catch (err) {
      objRes.err = err.toString();
      objRes.isSuccess = false;
      objRes.newId = -1;
      sendProgress = null;
      receiveProgress = null;
    }
    return objRes;
  }

#example end

您必須使用 Future、await 和 async,它們在后台線程中繼續流的任務,而您的應用程序的 UI 工作順利。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM