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
|
## 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.
|
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]
|
/// 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.
|
/// 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
|
/// 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
|
/// cached (particularly those picked from cloud providers), you may want to set [onFileLoading] handler
|
||||||
/// that will give you the current status of picking.
|
/// that will give you the current status of picking.
|
||||||
|
@ -64,6 +67,7 @@ abstract class FilePicker extends PlatformInterface {
|
||||||
bool allowCompression,
|
bool allowCompression,
|
||||||
bool allowMultiple = false,
|
bool allowMultiple = false,
|
||||||
bool withData,
|
bool withData,
|
||||||
|
bool withReadStream,
|
||||||
}) async =>
|
}) async =>
|
||||||
throw UnimplementedError('pickFiles() has not been implemented.');
|
throw UnimplementedError('pickFiles() has not been implemented.');
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:file_picker/src/platform_file.dart';
|
import 'package:file_picker/src/platform_file.dart';
|
||||||
|
@ -25,6 +26,7 @@ class FilePickerIO extends FilePicker {
|
||||||
bool allowCompression = true,
|
bool allowCompression = true,
|
||||||
bool allowMultiple = false,
|
bool allowMultiple = false,
|
||||||
bool withData = false,
|
bool withData = false,
|
||||||
|
bool withReadStream = false,
|
||||||
}) =>
|
}) =>
|
||||||
_getPath(
|
_getPath(
|
||||||
type,
|
type,
|
||||||
|
@ -33,6 +35,7 @@ class FilePickerIO extends FilePicker {
|
||||||
allowedExtensions,
|
allowedExtensions,
|
||||||
onFileLoading,
|
onFileLoading,
|
||||||
withData,
|
withData,
|
||||||
|
withReadStream,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -59,6 +62,7 @@ class FilePickerIO extends FilePicker {
|
||||||
List<String> allowedExtensions,
|
List<String> allowedExtensions,
|
||||||
Function(FilePickerStatus) onFileLoading,
|
Function(FilePickerStatus) onFileLoading,
|
||||||
bool withData,
|
bool withData,
|
||||||
|
bool withReadStream,
|
||||||
) async {
|
) async {
|
||||||
final String type = describeEnum(fileType);
|
final String type = describeEnum(fileType);
|
||||||
if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
|
if (type != 'custom' && (allowedExtensions?.isNotEmpty ?? false)) {
|
||||||
|
@ -87,8 +91,20 @@ class FilePickerIO extends FilePicker {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return FilePickerResult(
|
final List<PlatformFile> platformFiles = <PlatformFile>[];
|
||||||
result.map((file) => PlatformFile.fromMap(file)).toList());
|
|
||||||
|
for (final platformFileMap in result) {
|
||||||
|
platformFiles.add(
|
||||||
|
PlatformFile.fromMap(
|
||||||
|
platformFileMap,
|
||||||
|
readStream: withReadStream
|
||||||
|
? File(platformFileMap['path']).openRead()
|
||||||
|
: null,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FilePickerResult(platformFiles);
|
||||||
} on PlatformException catch (e) {
|
} on PlatformException catch (e) {
|
||||||
print('[$_tag] Platform exception: $e');
|
print('[$_tag] Platform exception: $e');
|
||||||
rethrow;
|
rethrow;
|
||||||
|
|
|
@ -12,6 +12,8 @@ class FilePickerWeb extends FilePicker {
|
||||||
Element _target;
|
Element _target;
|
||||||
final String _kFilePickerInputsDomId = '__file_picker_web-file-input';
|
final String _kFilePickerInputsDomId = '__file_picker_web-file-input';
|
||||||
|
|
||||||
|
final int _readStreamChunkSize = 1000 * 1000; // 1 MB
|
||||||
|
|
||||||
static final FilePickerWeb platform = FilePickerWeb._();
|
static final FilePickerWeb platform = FilePickerWeb._();
|
||||||
|
|
||||||
FilePickerWeb._() {
|
FilePickerWeb._() {
|
||||||
|
@ -43,6 +45,7 @@ class FilePickerWeb extends FilePicker {
|
||||||
Function(FilePickerStatus) onFileLoading,
|
Function(FilePickerStatus) onFileLoading,
|
||||||
bool allowCompression,
|
bool allowCompression,
|
||||||
bool withData = true,
|
bool withData = true,
|
||||||
|
bool withReadStream = false,
|
||||||
}) async {
|
}) async {
|
||||||
final Completer<List<PlatformFile>> filesCompleter =
|
final Completer<List<PlatformFile>> filesCompleter =
|
||||||
Completer<List<PlatformFile>>();
|
Completer<List<PlatformFile>>();
|
||||||
|
@ -63,12 +66,18 @@ class FilePickerWeb extends FilePicker {
|
||||||
final List<File> files = uploadInput.files;
|
final List<File> files = uploadInput.files;
|
||||||
final List<PlatformFile> pickedFiles = [];
|
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(
|
pickedFiles.add(PlatformFile(
|
||||||
name: file.name,
|
name: file.name,
|
||||||
path: path,
|
path: path,
|
||||||
size: bytes != null ? bytes.length ~/ 1024 : -1,
|
size: bytes != null ? bytes.length ~/ 1024 : file.size,
|
||||||
bytes: bytes,
|
bytes: bytes,
|
||||||
|
readStream: readStream,
|
||||||
));
|
));
|
||||||
|
|
||||||
if (pickedFiles.length >= files.length) {
|
if (pickedFiles.length >= files.length) {
|
||||||
|
@ -77,10 +86,15 @@ class FilePickerWeb extends FilePicker {
|
||||||
}
|
}
|
||||||
|
|
||||||
files.forEach((File file) {
|
files.forEach((File file) {
|
||||||
|
if (withReadStream) {
|
||||||
|
addPickedFile(file, null, null, _openFileReadStream(file));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!withData) {
|
if (!withData) {
|
||||||
final FileReader reader = FileReader();
|
final FileReader reader = FileReader();
|
||||||
reader.onLoadEnd.listen((e) {
|
reader.onLoadEnd.listen((e) {
|
||||||
addPickedFile(file, null, reader.result);
|
addPickedFile(file, null, reader.result, null);
|
||||||
});
|
});
|
||||||
reader.readAsDataUrl(file);
|
reader.readAsDataUrl(file);
|
||||||
return;
|
return;
|
||||||
|
@ -88,7 +102,7 @@ class FilePickerWeb extends FilePicker {
|
||||||
|
|
||||||
final FileReader reader = FileReader();
|
final FileReader reader = FileReader();
|
||||||
reader.onLoadEnd.listen((e) {
|
reader.onLoadEnd.listen((e) {
|
||||||
addPickedFile(file, reader.result, null);
|
addPickedFile(file, reader.result, null, null);
|
||||||
});
|
});
|
||||||
reader.readAsArrayBuffer(file);
|
reader.readAsArrayBuffer(file);
|
||||||
});
|
});
|
||||||
|
@ -129,4 +143,20 @@ class FilePickerWeb extends FilePicker {
|
||||||
}
|
}
|
||||||
return '';
|
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';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
class PlatformFile {
|
class PlatformFile {
|
||||||
|
@ -5,10 +6,11 @@ class PlatformFile {
|
||||||
this.path,
|
this.path,
|
||||||
this.name,
|
this.name,
|
||||||
this.bytes,
|
this.bytes,
|
||||||
|
this.readStream,
|
||||||
this.size,
|
this.size,
|
||||||
});
|
});
|
||||||
|
|
||||||
PlatformFile.fromMap(Map data)
|
PlatformFile.fromMap(Map data, {this.readStream})
|
||||||
: this.path = data['path'],
|
: this.path = data['path'],
|
||||||
this.name = data['name'],
|
this.name = data['name'],
|
||||||
this.bytes = data['bytes'],
|
this.bytes = data['bytes'],
|
||||||
|
@ -28,6 +30,9 @@ class PlatformFile {
|
||||||
/// or easily upload to somewhere else.
|
/// or easily upload to somewhere else.
|
||||||
final Uint8List bytes;
|
final Uint8List bytes;
|
||||||
|
|
||||||
|
/// File content as stream
|
||||||
|
final Stream<List<int>> readStream;
|
||||||
|
|
||||||
/// The file size in KB.
|
/// The file size in KB.
|
||||||
final int size;
|
final int size;
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
name: file_picker
|
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.
|
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
|
homepage: https://github.com/miguelpruivo/plugins_flutter_file_picker
|
||||||
version: 2.0.13
|
version: 2.1.0
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
|
|
Loading…
Reference in New Issue