Added withReadStream option to load a file in chunks (useful for large files)
This commit is contained in:
parent
d2d4de7bf8
commit
2aafd1131c
|
@ -1,3 +1,6 @@
|
|||
## 2.1.0
|
||||
Adds `withReadStream` that allows bigger files to be streamed read into a `Stream<List<int>>`. Thanks @redsolver.
|
||||
|
||||
## 2.0.13
|
||||
Updates `extension` helper getter to use the `name` property instead of `path`, since the latest isn't available on the Web, hence, the extension wouldn't be as well. Thank you @markgrancapal.
|
||||
|
||||
|
|
|
@ -49,6 +49,9 @@ abstract class FilePicker extends PlatformInterface {
|
|||
/// If [withData] is set, picked files will have its byte data immediately available on memory as [Uint8List]
|
||||
/// which can be useful if you are picking it for server upload or similar.
|
||||
///
|
||||
/// If [withReadStream] is set, picked files will have its byte data available as a [Stream<List<int>>]
|
||||
/// which can be useful for uploading and processing large files.
|
||||
///
|
||||
/// If you want to track picking status, for example, because some files may take some time to be
|
||||
/// cached (particularly those picked from cloud providers), you may want to set [onFileLoading] handler
|
||||
/// that will give you the current status of picking.
|
||||
|
@ -64,6 +67,7 @@ abstract class FilePicker extends PlatformInterface {
|
|||
bool allowCompression,
|
||||
bool allowMultiple = false,
|
||||
bool withData,
|
||||
bool withReadStream,
|
||||
}) async =>
|
||||
throw UnimplementedError('pickFiles() has not been implemented.');
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:file_picker/src/platform_file.dart';
|
||||
|
@ -25,6 +26,7 @@ class FilePickerIO extends FilePicker {
|
|||
bool allowCompression = true,
|
||||
bool allowMultiple = false,
|
||||
bool withData = false,
|
||||
bool withReadStream = false,
|
||||
}) =>
|
||||
_getPath(
|
||||
type,
|
||||
|
@ -33,6 +35,7 @@ class FilePickerIO extends FilePicker {
|
|||
allowedExtensions,
|
||||
onFileLoading,
|
||||
withData,
|
||||
withReadStream,
|
||||
);
|
||||
|
||||
@override
|
||||
|
@ -59,6 +62,7 @@ class FilePickerIO extends FilePicker {
|
|||
List<String> allowedExtensions,
|
||||
Function(FilePickerStatus) onFileLoading,
|
||||
bool withData,
|
||||
bool withReadStream,
|
||||
) async {
|
||||
final String type = describeEnum(fileType);
|
||||
if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
|
||||
|
@ -87,8 +91,20 @@ class FilePickerIO extends FilePicker {
|
|||
return null;
|
||||
}
|
||||
|
||||
return FilePickerResult(
|
||||
result.map((file) => PlatformFile.fromMap(file)).toList());
|
||||
final List<PlatformFile> platformFiles = <PlatformFile>[];
|
||||
|
||||
for (final platformFileMap in result) {
|
||||
platformFiles.add(
|
||||
PlatformFile.fromMap(
|
||||
platformFileMap,
|
||||
readStream: withReadStream
|
||||
? File(platformFileMap['path']).openRead()
|
||||
: null,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return FilePickerResult(platformFiles);
|
||||
} on PlatformException catch (e) {
|
||||
print('[$_tag] Platform exception: $e');
|
||||
rethrow;
|
||||
|
|
|
@ -12,6 +12,8 @@ class FilePickerWeb extends FilePicker {
|
|||
Element _target;
|
||||
final String _kFilePickerInputsDomId = '__file_picker_web-file-input';
|
||||
|
||||
final int _readStreamChunkSize = 1000 * 1000; // 1 MB
|
||||
|
||||
static final FilePickerWeb platform = FilePickerWeb._();
|
||||
|
||||
FilePickerWeb._() {
|
||||
|
@ -43,6 +45,7 @@ class FilePickerWeb extends FilePicker {
|
|||
Function(FilePickerStatus) onFileLoading,
|
||||
bool allowCompression,
|
||||
bool withData = true,
|
||||
bool withReadStream = false,
|
||||
}) async {
|
||||
final Completer<List<PlatformFile>> filesCompleter =
|
||||
Completer<List<PlatformFile>>();
|
||||
|
@ -63,12 +66,18 @@ class FilePickerWeb extends FilePicker {
|
|||
final List<File> files = uploadInput.files;
|
||||
final List<PlatformFile> pickedFiles = [];
|
||||
|
||||
void addPickedFile(File file, Uint8List bytes, String path) {
|
||||
void addPickedFile(
|
||||
File file,
|
||||
Uint8List bytes,
|
||||
String path,
|
||||
Stream<List<int>> readStream,
|
||||
) {
|
||||
pickedFiles.add(PlatformFile(
|
||||
name: file.name,
|
||||
path: path,
|
||||
size: bytes != null ? bytes.length ~/ 1024 : -1,
|
||||
size: bytes != null ? bytes.length ~/ 1024 : file.size,
|
||||
bytes: bytes,
|
||||
readStream: readStream,
|
||||
));
|
||||
|
||||
if (pickedFiles.length >= files.length) {
|
||||
|
@ -77,10 +86,15 @@ class FilePickerWeb extends FilePicker {
|
|||
}
|
||||
|
||||
files.forEach((File file) {
|
||||
if (withReadStream) {
|
||||
addPickedFile(file, null, null, _openFileReadStream(file));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!withData) {
|
||||
final FileReader reader = FileReader();
|
||||
reader.onLoadEnd.listen((e) {
|
||||
addPickedFile(file, null, reader.result);
|
||||
addPickedFile(file, null, reader.result, null);
|
||||
});
|
||||
reader.readAsDataUrl(file);
|
||||
return;
|
||||
|
@ -88,7 +102,7 @@ class FilePickerWeb extends FilePicker {
|
|||
|
||||
final FileReader reader = FileReader();
|
||||
reader.onLoadEnd.listen((e) {
|
||||
addPickedFile(file, reader.result, null);
|
||||
addPickedFile(file, reader.result, null, null);
|
||||
});
|
||||
reader.readAsArrayBuffer(file);
|
||||
});
|
||||
|
@ -129,4 +143,20 @@ class FilePickerWeb extends FilePicker {
|
|||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
Stream<List<int>> _openFileReadStream(File file) async* {
|
||||
final reader = FileReader();
|
||||
|
||||
int start = 0;
|
||||
while (start < file.size) {
|
||||
final end = start + _readStreamChunkSize > file.size
|
||||
? file.size
|
||||
: start + _readStreamChunkSize;
|
||||
final blob = file.slice(start, end);
|
||||
reader.readAsArrayBuffer(blob);
|
||||
await reader.onLoad.first;
|
||||
yield reader.result;
|
||||
start += _readStreamChunkSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import 'dart:async';
|
||||
import 'dart:typed_data';
|
||||
|
||||
class PlatformFile {
|
||||
|
@ -5,10 +6,11 @@ class PlatformFile {
|
|||
this.path,
|
||||
this.name,
|
||||
this.bytes,
|
||||
this.readStream,
|
||||
this.size,
|
||||
});
|
||||
|
||||
PlatformFile.fromMap(Map data)
|
||||
PlatformFile.fromMap(Map data, {this.readStream})
|
||||
: this.path = data['path'],
|
||||
this.name = data['name'],
|
||||
this.bytes = data['bytes'],
|
||||
|
@ -28,6 +30,9 @@ class PlatformFile {
|
|||
/// or easily upload to somewhere else.
|
||||
final Uint8List bytes;
|
||||
|
||||
/// File content as stream
|
||||
final Stream<List<int>> readStream;
|
||||
|
||||
/// The file size in KB.
|
||||
final int size;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
name: file_picker
|
||||
description: A package that allows you to use a native file explorer to pick single or multiple absolute file paths, with extension filtering support.
|
||||
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
|
||||
version: 2.0.13
|
||||
version: 2.1.0
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
|
|
Loading…
Reference in New Issue