Flutter flatterweb:如何上传大文件?
有没有办法把大文件上传到服务器上 我使用Flutter flatterweb:如何上传大文件?,flutter,file-upload,out-of-memory,large-files,flutter-web,Flutter,File Upload,Out Of Memory,Large Files,Flutter Web,有没有办法把大文件上传到服务器上 我使用MultipartRequest与MultipartFile类似: List<int> fileBytes) async { var request = new http.MultipartRequest("POST", Uri.parse(url)); request.files.add(http.MultipartFile.fromBytes( 'file', fileBytes, c
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);
对于30 MB左右的文件,这是可以的,但如果超过30 MB,我会得到错误代码:内存不足
。
我做错什么了吗?我在某处看到
MultipartFile.fromBytes会在较大的文件上给您带来一些问题,因为浏览器会限制您的内存消耗
我认为他的解决方案是:
有一个fromStream构造函数。通常,对于较大的文件,我只使用HttpRequest,并将File对象放在FormData实例中
我使用了
MultipartFile
和MultipartFile.fromString
,这两次(对于150MB的文件)都再次发生。
如何使用此解决方案?或者对于超过500 MB的文件有更好的方法吗
更新
使用
Worker
添加了答案。这不是一个很好的解决方案,但我希望这可能会帮助一些人。如果您有更好/正确的解决方案,请告知我们,我将更改已接受的答案。目前,我使用以下方法解决了问题:
进口:
import 'package:universal_html/html.dart' as html;
颤振部分:
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"),
),
],
);
}
}
实际上,不要使用
fromBytes
命名构造函数,因为它需要500 MB字节的缓冲区-而是使用我使用的其他MultipartFile
和MultipartFile.fromString
以及这两个时间(对于150 MB的文件)再次发生。这就是为什么我认为我在这里做错了什么。对于fromString
我可以使用reader.result.toString()
对吗?试试看,在web上不起作用。你找到解决方法了吗?找到了。谢谢你的分享,我很高兴这有帮助。
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"),
),
],
);
}
}
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);
}