字节笔记本

2026年3月22日

Flutter File Picker - 文件选择器插件

本文介绍 flutter_file_picker,一个功能全面的 Flutter 文件选择器插件,兼容移动端、Web 端和桌面端(macOS、Linux、Windows)全平台,并支持 Flutter Go 和 WebAssembly 编译。

项目简介

flutter_file_picker 是由开发者 Miguel Ruivo 创建的开源 Flutter 插件,它允许开发者使用操作系统原生的文件浏览器来选取单个或多个文件,并支持扩展名过滤功能。该插件覆盖了 Flutter 所有的主要平台,是目前 Flutter 生态中使用最广泛的文件选择解决方案之一。

项目已被收录在 Awesome Flutter 列表中,拥有完善的 CI/CD 流水线,持续保持活跃维护。插件在 pub.dev 上以 file_picker 的包名发布,获得了社区的高度认可。

核心特性

原生文件选择器体验

插件直接调用各操作系统原生的文件浏览器,为用户提供最熟悉、最自然的文件选择体验。无论是在 Android、iOS、macOS、Linux、Windows 还是 Web 平台上,用户看到的都是系统标准的文件选择界面。

全平台兼容

插件支持以下所有 Flutter 可用的平台:

  • Android:使用系统原生文件选择器
  • iOS:使用 iOS 原生文件选择器
  • Web:支持标准 Web 和 WebAssembly(Wasm)编译
  • macOS:使用 macOS 原生文件选择器
  • Linux:使用 GTK 原生文件对话框
  • Windows:使用 Windows 原生文件对话框

多种选择模式

插件提供了灵活的文件选择方式:

  • 单文件选择:选取单个文件
  • 多文件选择:同时选取多个文件
  • 目录选择:选择文件夹路径
  • 文件和目录同时选择:在 macOS 上支持同时选取文件和目录

扩展名过滤

支持通过自定义文件扩展名列表来过滤可选择的文件类型:

dart
allowedExtensions: ['jpg', 'pdf', 'doc']

默认类型过滤

内置多种常用的文件类型过滤预设:

  • media:媒体文件(图片、视频、音频)
  • image:仅图片文件
  • video:仅视频文件
  • audio:仅音频文件
  • any:任意类型文件

云文件支持

支持从云端存储服务中选择文件,包括:

  • Google Drive
  • Dropbox
  • iCloud

保存文件对话框

除了选择文件,插件还支持打开"保存文件/另存为"对话框,让用户指定要保存文件的驱动器、目录和文件名。

XFile 跨平台支持

选择结果以 XFile(cross_file)形式返回,方便与其他 Flutter 库(如 image_picker 等)配合使用。

技术栈

API 兼容性矩阵

插件各 API 在不同平台上的支持情况如下:

APIAndroidiOSLinuxmacOSWindowsWeb
clearTemporaryFiles()支持支持----
getDirectoryPath()支持支持支持支持支持-
pickFileAndDirectoryPaths()---支持--
pickFiles()支持支持支持支持支持支持
saveFile()支持支持支持支持支持支持

核心实现

插件通过 Flutter 的平台通道(Platform Channel)机制,在各平台上分别调用原生 API 实现文件选择功能。Web 端则通过 Dart 的 Web API 实现,同时支持 Wasm 编译。

安装指南

添加依赖

pubspec.yaml 中添加依赖:

yaml
dependencies:
  file_picker: ^latest_version

或者通过命令行添加:

bash
flutter pub add file_picker

导入包

dart
import 'package:file_picker/file_picker.dart';

平台配置

详细的平台配置请参考官方 Wiki,每个平台都有特定的配置要求和注意事项:

  1. Android:通常无需额外配置,注意权限管理
  2. iOS:在 Info.plist 中添加必要的权限描述
  3. Web:确保 web/index.html 中的内容安全策略允许文件访问
  4. Desktop(macOS/Linux/Windows):确保桌面端支持已启用

快速开始

选择单个文件

最简单的使用方式,一行代码即可调起文件选择器:

dart
FilePickerResult? result = await FilePicker.platform.pickFiles();

if (result != null) {
  File file = File(result.files.single.path!);
} else {
  // 用户取消了选择
}

选择多个文件

通过设置 allowMultiple 参数实现多文件选择:

dart
FilePickerResult? result = await FilePicker.platform.pickFiles(
  allowMultiple: true,
);

if (result != null) {
  List<File> files = result.paths.map((path) => File(path!)).toList();
} else {
  // 用户取消了选择
}

按扩展名过滤

通过 typeallowedExtensions 参数组合实现文件类型过滤:

dart
FilePickerResult? result = await FilePicker.platform.pickFiles(
  allowMultiple: true,
  type: FileType.custom,
  allowedExtensions: ['jpg', 'pdf', 'doc'],
);

选择目录

使用 getDirectoryPath() 方法选择文件夹:

dart
String? selectedDirectory = await FilePicker.platform.getDirectoryPath();

if (selectedDirectory == null) {
  // 用户取消了选择
}

保存文件对话框

使用 saveFile() 方法打开保存文件对话框:

dart
String? outputFile = await FilePicker.platform.saveFile(
  dialogTitle: '请选择输出文件:',
  fileName: 'output-file.pdf',
);

if (outputFile == null) {
  // 用户取消了选择
}

使用示例

获取文件详细信息

通过 PlatformFile 对象可以获取选中文件的详细属性:

dart
FilePickerResult? result = await FilePicker.platform.pickFiles();

if (result != null) {
  PlatformFile file = result.files.first;

  print(file.name);       // 文件名
  print(file.bytes);      // 文件字节数据(Web 端可用)
  print(file.size);       // 文件大小
  print(file.extension);  // 文件扩展名
  print(file.path);       // 文件路径
}

获取 XFile 列表

选择结果可以转换为 XFile 格式,便于与其他库配合:

dart
FilePickerResult? result = await FilePicker.platform.pickFiles();

if (result != null) {
  // 获取所有文件的 XFile 列表
  List<XFile> xFiles = result.xFiles;

  // 获取单个文件的 XFile
  XFile xFile = result.files.first.xFile;
}

选择并上传文件到 Firebase Storage(Web 端)

在 Web 端,可以直接获取文件的字节数据进行上传:

dart
FilePickerResult? result = await FilePicker.platform.pickFiles();

if (result != null) {
  Uint8List fileBytes = result.files.first.bytes!;
  String fileName = result.files.first.name;

  // 上传到 Firebase Storage
  await FirebaseStorage.instance
      .ref('uploads/$fileName')
      .putData(fileBytes);
}

使用默认类型过滤

内置的文件类型过滤预设可以快速筛选特定类型的文件:

dart
// 仅选择图片
FilePickerResult? result = await FilePicker.platform.pickFiles(
  type: FileType.image,
);

// 仅选择视频
FilePickerResult? result = await FilePicker.platform.pickFiles(
  type: FileType.video,
);

// 仅选择音频
FilePickerResult? result = await FilePicker.platform.pickFiles(
  type: FileType.audio,
);

// 选择媒体文件(图片、视频、音频)
FilePickerResult? result = await FilePicker.platform.pickFiles(
  type: FileType.media,
);

// 选择任意类型文件
FilePickerResult? result = await FilePicker.platform.pickFiles(
  type: FileType.any,
);

清理临时文件

在 Android 和 iOS 平台上,选择文件后可能产生临时文件,可以使用以下方法清理:

dart
await FilePicker.platform.clearTemporaryFiles();

云文件选择

在支持的平台(如 iOS)上,文件选择器会自动显示 iCloud 等云存储选项。用户可以在文件选择界面中切换到"iCloud 云盘"或"我的 iPhone"等位置来选择云端文件。

常见问题

Web 端文件路径

在 Web 端,PlatformFile.path 可能为空或为 blob URL。如果需要在 Web 端处理文件内容,请使用 PlatformFile.bytes 属性直接获取文件字节数据。

桌面端配置

确保在使用桌面端之前已启用对应的桌面支持:

bash
flutter config --enable-macos-desktop
flutter config --enable-linux-desktop
flutter config --enable-windows-desktop

iOS 权限配置

Info.plist 中添加必要的权限描述:

xml
<key>NSDocumentsFolderUsageDescription</key>
<string>需要访问文档文件夹以选择文件。</string>

项目链接

该插件是 Flutter 项目中处理文件选择需求的标准解决方案,API 设计简洁直观,文档完善,社区活跃。无论是简单的单文件选择还是复杂的文件管理需求,flutter_file_picker 都能提供可靠的支持。

分享: