file_selector
安装🛠
点击
file_selector
获取最新版本。以下是在编写本文章时的最新版本:
file_selector: ^0.8.4+1
👻注意:在开发 macOS 端的程序时,还需要额外的操作,具体可以查看
这里
了解🧩
在 file_selector 插件中,我们需要了解对象 XTypeGroup 和方法 openFiles。
XTypeGroup的作用是使用给定的标签和文件扩展名创建一个新组,没有提供任何类型选项的组表示允许任何类型。
XTypeGroup 可以传入5个参数:
-
-
String? label
:用来自己作区分
-
List<String>? extensions
:过滤非描述的后缀文件,默认加载全部类型的文件
-
List<String>? mimeTypes
:主要针对 Linux 系统下的文件类型
-
List<String>? macUTIs
:主要针对 mac 系统下的文件类型
-
List<String>? webWildCards
:主要针对网页开发时的类型
openFile 方法返回一个 XFile 对象,可以传入3个参数:
-
-
List acceptedTypeGroups = const []
:接受的类型组,传入一个XTypeGroup列表
-
String? initialDirectory
:初始化文件夹。打开文件对话框以加载文件并返回文件路径
-
String? confirmButtonText
:弹窗“打开”按钮的显示文字
openFiles 方法返回 XFile 对象列表,传入的参数和 openFile 一样。
使用🥩
选择的文件我们最后需要读取出来,读取需要接受一个 String 类型的路径:
String path = '';
这里先以选择图片为例,我们需要先定义一个 XTypeGroup 对象:
final xType = XTypeGroup(label: '图片', extensions: ['jpg', 'png']);
选择单张图片
打开弹窗选取单个文件,使用 openFile 方法:
final XFile? file = await openFile(acceptedTypeGroups: [xType]);
将获取到的 XFile 对象的路径值传给 path。当然,并不是每次打开弹窗都会选择图片,所以需要判断一下:
if (file != null) {
path = file.path;
setState((){});
} else {
BotToast.showText(text: '你不选择图片打开干啥😤');
}
openFile 方法中还有两个属性,我们修改试一下:
final XFile? file = await openFile(
acceptedTypeGroups: [xType],
initialDirectory: r'C:\Users\ilgnefz\Pictures',
confirmButtonText: '嘿嘿嘿',
);
initialDirectory 属性貌似没用😕去看了官方的例子,也没用到过这个参数,以后就忽略它吧。
选择多张图片
选取多张图片,我们就需要定义一个路径的数组了:
final List<String> paths = []
XTypeGroup 对象和刚才的一样就行,重要的是使用 openFiles 方法:
final List<XFile> files = await openFiles(acceptedTypeGroups: [xType]);
将获取到的文件路径列表赋值给 paths:
if (file != null) {
paths.addAll(files.map((e) => e.path).toList());
setState((){});
} else {
BotToast.showText(text: '你不选择图片打开干啥😤');
}
好了,来看看效果如何
读取文本文件
读取文本文件,我们需要获取文件的名称和内容:
final String title = '';
final String content = '';
再更改一下 XTypeGroup 对象就行:
final XTypeGroup xType = XTypeGroup(label: '文本', extensions: ['txt']);
final XFile? file = await openFile(acceptedTypeGroups: [xType]);
将获取到的 XFile 对象的属性赋值给我们定义的对象:
if (file != null) {
title = file.name;
content = await file.readAsString();
setState((){});
} else {
BotToast.showText(text: '打开了个寂寞🙄');
}
存储文本文件
存储文本需要用到 XFile 对象中的 fromData 方法。让我们来看看这个方法中需要传入什么参数:
-
-
Uint8List bytes
:存储的主要内容
-
String? mimeType
:文件的 mine 类型
-
String? name
:文件名?测试了毫无用处😑
-
int? length
:不知道是什么的长度,反正无法截取内容😑
-
DateTime? lastModified
:最后修改文件的时间
-
String? path
:文件保存的路径?测试了毫无效果😑
-
CrossFileTestOverrides? overrides
:覆盖CrossFile的某些方法用来测试
(以上几个参数要是有朋友测试出来了,可以告知一下😁)
在存储文本文件前,我们需要先知道应该存储在哪个文件夹:
final String? path = await getSavePath();
然后再把 XFile.fromData 需要的参数放进去:
if (path != null) {
// 将内容编码成utf8
final Uint8List fileData = const Utf8Encoder().convert(content);
const String fileMimeType = 'text/plain';
final XFile xFile = XFile.fromData(
fileData,
mimeType: fileMimeType,
name: title,
await xFile.saveTo(path);
} else {
BotToast.showText(text: '给你个眼神自己体会😑');
}
获取文件夹路径
读取文件夹路径需要使用 getDirectoryPath 方法:
final String? path = await getDirectoryPath();
if (path != null) {
title = '目录';
content = path;
setState((){});
}
file_picker
安装🛠
点击
file_picker
获取最新版本。以下是在编写本文章时的最新版本:
file_picker: ^4.5.1
使用🥩
先定义一个默认的路径:
String path = '';
选择单个文件
选择单个文件需要用到 pickFiles 方法,该方法可以传入10个参数:
-
-
String? dialogTitle
:弹窗的标题
-
String? initialDirectory
:初始化的文件夹
-
FileType type = FileType.any
:文件的类型
-
List<String>? allowedExtensions
:允许的文件后缀名称
-
dynamic Function(FilePickerStatus)? onFileLoading
:监听文件选择的状态
-
bool allowCompression = true
:是否允许压缩
-
bool allowMultiple = false
:是否允许选择多个文件
-
bool withData = false
:如果为true,选取的文件将在内存中立即以“Uint8List”的形式提供其字节数据,如果您选择它进行服务器上传或类似操作,这将很有用。但是,请记住,如果您允许多个选择或选择大文件,则在 IO(iOS 和 Android)上启用此功能可能会导致内存不足问题。请改用 [withReadStream]。在 web 上默认为
true
,其他为
false
-
bool withReadStream = false
:拾取的文件将以 [Stream<List>] 的形式提供其字节数据,这对于上传和处理大文件很有用
-
bool lockParentWindow = false
:是否将子窗口(文件选择器窗口)一直停留在 Flutter 窗口的前面,直到它关闭(如模态窗口)。此参数仅适用于 Windows
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
File file = File(result.files.single.path!);
path = file.path;
setState((){});
}
我们试着添加一些参数:
FilePickerResult? result = await FilePicker.platform.pickFiles(
dialogTitle: '我的地盘我做主',
initialDirectory: r'C:\Users\ilgnefz\Pictures\Saved Pictures',
type: FileType.image,
);
initialDirectory 又没起作用😑
选择多个文件
定义一个接受所有路径的数组:
final List<String> paths = [];
FilePickerResult? result = await FilePicker.platform.pickFiles(
allowMultiple: true,
if (result != null) {
paths = result.files.map((e) => e.path!).toList();
setState((){});
}
读取文件信息
通过以上的方法,我们会得到一个 PlatformFile 对象:
FilePickerResult? result = await FilePicker.platform.pickFiles();
PlatformFile file = result.files.single;
该对象有以下几个属性:
-
-
name
:文件名称
-
size
:文件大小,以字节为单位
-
bytes
:此文件的字节数据。如果您想操作其数据或轻松上传到其他地方,则特别有用。
在常见问题解答中查看此处
一个关于如何使用它在网络上上传的示例。
-
extension
:文件后缀
-
path
:文件路径
-
identifier
:原始文件的平台标识符,是指 Android 上的
Uri
和 iOS 上的
NSURL
。其他为null
-
readStream
:将文件内容转换成流读取
存储文件
存储文件需要使用 saveFile 方法,该方法有可以传入6个参数:
-
-
String? dialogTitle
:同 pickFiles 方法
-
String? fileName
:存储文件的名字
-
String? initialDirectory
:同 pickFiles 方法
-
FileType type = FileType.any
:同 pickFiles 方法
-
List ? allowedExtensions
:同 pickFiles 方法
-
bool lockParentWindow = false
:同 pickFiles 方法
String? outputFile = await FilePicker.platform.saveFile();
(⊙o⊙)…这个方法连保存内容的参数都没有,诶!就是玩😄。官方说这个方法没有实际意义。
获取文件夹路径
获取文件夹需要使用 getDirectoryPath 方法,可以传入3个参数:
-
-
String? dialogTitle
:同 pickFiles 方法
-
bool lockParentWindow = false
:同 pickFiles 方法
-
String? initialDirectory
:同 pickFiles 方法
final String title = '';
final String content = '';
String? dir = await FilePicker.platform.getDirectoryPath();
if (path != null) {
title = '目录';
content = path;
setState((){});
}
🛫OK,以上就是这篇文章的全部内容,仅针对插件的当前版本,并不能保证适用于以后插件用法的更新迭代。
最后,感谢
flutter
团队和
miguelpruivo
对以上插件的开发和维护😁。本应用代码已上传至
github
和
gitee
,有需要的可以下载下来查看学习。