有没有办法将大文件上传到服务器?
我将 MultipartRequest
与 MultipartFile
一起使用,例如:
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 的文件,我会得到 错误代码:内存不足
。
我做错了什么吗?我在某处看到了
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.
我使用了 MultipartFile
和 MultipartFile.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/