flutter 网络 : How to Upload a Large File?

标签 flutter file-upload out-of-memory large-files flutter-web

有没有办法将大文件上传到服务器?

我将 MultipartRequestMultipartFile 一起使用,例如:

  List<int> fileBytes) async {
  var request = new http.MultipartRequest("POST", Uri.parse(url));
  request.files.add(http.MultipartFile.fromBytes(
    'file',
    fileBytes,
    contentType: MediaType('application', 'octet-stream'),
    filename: fileName));
  request.headers.addAll(headers);
  var streamedResponse = await request.send();
  return await http.Response.fromStream(streamedResponse);

并像这样读取文件:

    html.InputElement uploadInput = html.FileUploadInputElement();
    uploadInput.multiple = false;
    uploadInput.draggable = true;
    uploadInput.click();

    uploadInput.onChange.listen((e) {
      final files = uploadInput.files;
      final file = files[0];

      final reader = new html.FileReader();

      reader.onLoadEnd.listen((e) {
        setState(() {
          _bytesData =
              Base64Decoder().convert(reader.result.toString().split(",").last);
          _selectedFile = _bytesData;
        });
      });

      reader.readAsDataUrl(file);
    });

对于大约 30 MB 的文件是可以的,但对于超过 30 MB 的文件,我会得到 错误代码:内存不足enter image description here

我做错了什么吗?我在某处看到了

MultipartFile.fromBytes will give you some issues on bigger files, as the browser will limit your memory consumption.

我认为他的解决方案是:

There’s a fromStream constructor. Usually, for bigger files, I just use HttpRequest, and put the File object in a FormData instance.

我使用了 MultipartFileMultipartFile.fromString 并且两次(对于 150 MB 文件)都再次发生。 我该如何使用这个解决方案?或者对于超过 500 MB 的文件有更好的方法吗?

更新

使用 Worker 添加了一个答案。这不是一个很好的解决方案,但我认为这可能会对某人有所帮助。

最佳答案

目前,我使用这种方法解决了这个问题:

导入:

import 'package:universal_html/html.dart' as html;

flutter 部分:

class Upload extends StatefulWidget {
  @override
  _UploadState createState() => _UploadState();
}

class _UploadState extends State<Upload> {
  html.Worker myWorker;
  html.File file;

  _uploadFile() async {
    String _uri = "/upload";

    myWorker.postMessage({"file": file, "uri": _uri});
  }

  _selectFile() {
    html.InputElement uploadInput = html.FileUploadInputElement();
    uploadInput.multiple = false;
    uploadInput.click();

    uploadInput.onChange.listen((e) {
      file = uploadInput.files.first;
    });
  }

  @override
  void initState() {
    myWorker = new html.Worker('upload_worker.js');
    myWorker.onMessage.listen((e) {
      setState(() {
        //progressbar,...
      });
    });

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        RaisedButton(
          onPressed: _selectFile(),
          child: Text("Select File"),
        ),
        RaisedButton(
          onPressed: _uploadFile(),
          child: Text("Upload"),
        ),
      ],
    );
  }
}

Javascript 部分:

在 web 文件夹中(在 index.html 旁边),创建文件“upload_worker.js”。

self.addEventListener('message', async (event) => {
    var file = event.data.file;
    var url = event.data.uri;
    uploadFile(file, url);
});

function uploadFile(file, url) {
    var xhr = new XMLHttpRequest();
    var formdata = new FormData();
    var uploadPercent;

    formdata.append('file', file);

    xhr.upload.addEventListener('progress', function (e) {
        //Use this if you want to have a progress bar
        if (e.lengthComputable) {
            uploadPercent = Math.floor((e.loaded / e.total) * 100);
            postMessage(uploadPercent);
        }
    }, false);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            postMessage("done");
        }
    }
    xhr.onerror = function () {
        // only triggers if the request couldn't be made at all
        postMessage("Request failed");
    };

    xhr.open('POST', url, true);

    xhr.send(formdata);
}

关于 flutter 网络 : How to Upload a Large File?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63643315/

相关文章:

firebase - 在 Flutter 中添加记录时,Cloud Firestore 无法正确更新

java - 有没有办法增加从 NetBeans 启动的应用程序中的虚拟内存?

java - 使用netty高速发送消息时出现OOM异常

ios - 如何为 Flutter 应用程序创建 iOS LaunchScreen.storyboard?

flutter - 是否可以减少代码的编写以取出例如 : ref. read(countProvider.notifier) - 在构建方法中?

php - 找到内存限制和(upload_max_filesize & post_max_size)的最佳平衡

php - 无法上传面临警告 : move_uploaded_file 的文件

asp.net - 上传前设置文件路径和名称属性

Android有效地将图像加载到imageview中

ios - Flutter Audioplayers插件不播放声音,而是卡住了该应用程序