
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
🎯 前言:为什么需要文件路径管理?
在移动应用开发中,文件路径管理是一个基础且重要的功能:
场景一 :应用需要保存用户下载的文件到合适的目录
场景二 :应用需要缓存图片、视频等媒体文件
场景三 :应用需要存储用户配置文件
场景四 :应用需要访问设备的外部存储
场景五:应用需要读写临时文件
path_provider 是解决这些需求的完美方案!它提供了一套跨平台的文件路径 API,让应用可以轻松地访问系统目录。
🚀 核心能力一览
| 功能特性 | 详细说明 | OpenHarmony 支持 |
|---|---|---|
| 应用目录 | 获取应用专属目录 | ✅ |
| 临时目录 | 获取临时文件目录 | ✅ |
| 文档目录 | 获取公共文档目录 | ✅ |
| 下载目录 | 获取公共下载目录 | ✅ |
| 外部存储 | 访问外部存储(受限) | ✅ |
| 跨平台一致 | 所有平台行为一致 | ✅ |
支持的目录类型
path_provider 支持以下目录类型:
| 方法 | 用途 | Android | iOS | Windows | macOS | Linux | OpenHarmony |
|---|---|---|---|---|---|---|---|
| getApplicationSupportDirectory | 应用支持目录 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| getApplicationDocumentsDirectory | 应用文档目录 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| getApplicationCacheDirectory | 应用缓存目录 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| getTemporaryDirectory | 临时文件目录 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| getExternalStorageDirectory | 外部存储目录 | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
| getDownloadsDirectory | 下载目录 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
📱 如何运行这些示例
运行步骤
- 创建新项目或使用现有项目
- 配置依赖(见下方)
- 配置权限(见下方)
- 复制示例代码到
lib/main.dart - 运行应用:
flutter run
⚠️ 常见问题
- 问题 :无法访问外部存储
- 解决:检查是否配置了存储权限
⚙️ 环境准备:三步走
第一步:添加依赖
📄 pubspec.yaml:
yaml
dependencies:
flutter:
sdk: flutter
# 添加 path_provider 依赖(OpenHarmony 适配版本)
path_provider:
git:
url: https://atomgit.com/openharmony-tpc/flutter_packages
path: packages/path_provider/path_provider
执行命令:
bash
flutter pub get
第二步:配置权限
2.1 配置存储权限(可选)
如果需要访问外部存储目录,需要配置存储权限。
📄 ohos/entry/src/main/module.json5:
json
{
"module": {
"requestPermissions": [
{
"name": "ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY",
"reason": "$string:storage_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
}
}
2.2 配置权限说明
📄 ohos/entry/src/main/resources/base/element/string.json:
json
{
"string": [
{
"name": "storage_reason",
"value": "访问和管理文件"
}
]
}
第三步:初始化平台实例
📄 lib/main.dart:
dart
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Path Provider Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF9C27B0)),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
📸 场景一:获取应用目录路径
📝 完整代码
dart
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String _appSupportDir = '';
String _appDocumentsDir = '';
String _appCacheDir = '';
String _tempDir = '';
@override
void initState() {
super.initState();
_loadPaths();
}
Future<void> _loadPaths() async {
setState(() {
_appSupportDir = '';
_appDocumentsDir = '';
_appCacheDir = '';
_tempDir = '';
});
try {
final appSupportDir = await getApplicationSupportDirectory();
final appDocumentsDir = await getApplicationDocumentsDirectory();
final appCacheDir = await getApplicationCacheDirectory();
final tempDir = await getTemporaryDirectory();
setState(() {
_appSupportDir = appSupportDir.path;
_appDocumentsDir = appDocumentsDir.path;
_appCacheDir = appCacheDir.path;
_tempDir = tempDir.path;
});
} catch (e) {
debugPrint('获取路径失败: $e');
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('文件路径示例'),
actions: [
IconButton(
onPressed: _loadPaths,
icon: const Icon(Icons.refresh),
tooltip: '刷新路径',
),
],
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
_buildPathCard(
icon: Icons.folder,
title: '应用支持目录',
subtitle: '应用专属支持文件',
path: _appSupportDir,
color: const Color(0xFF9C27B0),
),
const SizedBox(height: 16),
_buildPathCard(
icon: Icons.description,
title: '应用文档目录',
subtitle: '应用专属文档文件',
path: _appDocumentsDir,
color: const Color(0xFF6366F1),
),
const SizedBox(height: 16),
_buildPathCard(
icon: Icons.cached,
title: '应用缓存目录',
subtitle: '应用专属缓存文件',
path: _appCacheDir,
color: const Color(0xFF10B981),
),
const SizedBox(height: 16),
_buildPathCard(
icon: Icons.temp_preferences,
title: '临时目录',
subtitle: '系统临时文件',
path: _tempDir,
color: const Color(0xFFF59E0B),
),
],
),
);
}
Widget _buildPathCard({
required IconData icon,
required String title,
required String subtitle,
required String path,
required Color color,
}) {
return Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundColor: color.withOpacity(0.1),
child: Icon(icon, color: color),
),
title: Text(
title,
style: const TextStyle(fontWeight: FontWeight.w600),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(subtitle),
const SizedBox(height: 4),
Text(
path.isEmpty ? '加载中...' : path,
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
fontFamily: 'monospace',
),
overflow: TextOverflow.ellipsis,
),
],
),
trailing: path.isNotEmpty
? IconButton(
icon: const Icon(Icons.copy),
onPressed: () {
// 复制路径到剪贴板
},
tooltip: '复制路径',
)
: null,
),
);
}
}
🔑 关键点解析
- getApplicationSupportDirectory:获取应用支持目录,用于存储应用支持的文件
- getApplicationDocumentsDirectory:获取应用文档目录,用于存储用户文档
- getApplicationCacheDirectory:获取应用缓存目录,用于存储缓存文件
- getTemporaryDirectory:获取临时目录,用于存储临时文件
🖼️ 场景二:文件读写操作
📝 完整代码
dart
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class _HomePageState extends State<HomePage> {
// ... 其他代码
Future<void> _writeFile() async {
try {
final appDocumentsDir = await getApplicationDocumentsDirectory();
final file = File('${appDocumentsDir.path}/test.txt');
await file.writeAsString('Hello, OpenHarmony!');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件写入成功')),
);
}
} catch (e) {
debugPrint('写入文件失败: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('写入文件失败: $e')),
);
}
}
}
Future<void> _readFile() async {
try {
final appDocumentsDir = await getApplicationDocumentsDirectory();
final file = File('${appDocumentsDir.path}/test.txt');
if (await file.exists()) {
final content = await file.readAsString();
if (mounted) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('文件内容'),
content: Text(content),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('关闭'),
),
],
),
);
}
} else {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件不存在')),
);
}
}
} catch (e) {
debugPrint('读取文件失败: $e');
}
}
Future<void> _deleteFile() async {
try {
final appDocumentsDir = await getApplicationDocumentsDirectory();
final file = File('${appDocumentsDir.path}/test.txt');
if (await file.exists()) {
await file.delete();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件删除成功')),
);
}
} else {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件不存在')),
);
}
}
} catch (e) {
debugPrint('删除文件失败: $e');
}
}
}
🔑 关键点解析
- 导入 dart:io :使用
dart:io包中的File类进行文件操作 - 文件路径拼接 :使用
${dir.path}/filename拼接文件路径 - 检查文件存在 :
await file.exists()检查文件是否存在 - 异步文件操作 :所有文件操作都是异步的,需要使用
await
⚡ 高级技巧:封装文件服务类
为了简化文件操作,我们可以封装一个文件服务类:
📝 服务类代码
dart
import 'dart:io';
import 'package:path_provider/path_provider.dart';
class FileService {
static final FileService _instance = FileService._internal();
factory FileService() => _instance;
FileService._internal();
// 获取应用文档目录
Future<Directory> getAppDocumentsDir() async {
return await getApplicationDocumentsDirectory();
}
// 获取应用缓存目录
Future<Directory> getAppCacheDir() async {
return await getApplicationCacheDirectory();
}
// 写入文件
Future<void> writeFile(String filename, String content) async {
final dir = await getAppDocumentsDir();
final file = File('${dir.path}/$filename');
await file.writeAsString(content);
}
// 读取文件
Future<String?> readFile(String filename) async {
final dir = await getAppDocumentsDir();
final file = File('${dir.path}/$filename');
if (await file.exists()) {
return await file.readAsString();
}
return null;
}
// 删除文件
Future<void> deleteFile(String filename) async {
final dir = await getAppDocumentsDir();
final file = File('${dir.path}/$filename');
if (await file.exists()) {
await file.delete();
}
}
// 清空缓存目录
Future<void> clearCache() async {
final dir = await getAppCacheDir();
if (await dir.exists()) {
await dir.delete(recursive: true);
}
}
// 获取缓存大小
Future<int> getCacheSize() async {
final dir = await getAppCacheDir();
if (!await dir.exists()) {
return 0;
}
int totalSize = 0;
await for (final entity in dir.list(recursive: true)) {
if (entity is File) {
totalSize += await entity.length();
}
}
return totalSize;
}
}
// 使用示例
final fileService = FileService();
// 写入文件
await fileService.writeFile('config.json', '{"theme":"dark"}');
// 读取文件
String? content = await fileService.readFile('config.json');
// 清空缓存
await fileService.clearCache();
// 获取缓存大小
int cacheSize = await fileService.getCacheSize();
String cacheSizeText = '${(cacheSize / 1024).toStringAsFixed(2)} KB';
❓ 常见问题排查
Q1:获取路径返回 null?
dart
// 检查路径是否存在
final dir = await getApplicationDocumentsDirectory();
debugPrint('路径: ${dir.path}');
if (await dir.exists()) {
// 路径存在
} else {
// 路径不存在,创建目录
await dir.create(recursive: true);
}
Q2:无法访问外部存储?
dart
// 检查是否有权限
// 1. 确保在 module.json5 中配置了权限
// 2. 在运行时请求权限
Q3:文件写入失败?
dart
// 确保目录存在
final dir = await getApplicationDocumentsDirectory();
if (!await dir.exists()) {
await dir.create(recursive: true);
}
// 然后写入文件
final file = File('${dir.path}/test.txt');
await file.writeAsString('content');
Q4:缓存文件过多?
dart
// 定期清理缓存
Future<void> _cleanCacheIfNeeded() async {
final cacheSize = await fileService.getCacheSize();
// 如果缓存超过 10MB,清空缓存
if (cacheSize > 10 * 1024 * 1024) {
await fileService.clearCache();
}
}
🚀 性能优化建议
1. 使用缓存
dart
// 缓存目录路径
Directory? _cachedAppDocumentsDir;
Future<Directory> getAppDocumentsDir() async {
_cachedAppDocumentsDir ??= await getApplicationDocumentsDirectory();
return _cachedAppDocumentsDir!;
}
2. 批量操作
dart
// ❌ 不好的做法:逐个删除文件
for (var file in files) {
await file.delete();
}
// ✅ 好的做法:使用 Future.wait
await Future.wait(files.map((file) => file.delete()));
3. 异步流式处理
dart
// 对于大文件,使用流式读取
final file = File('${dir.path}/large_file.txt');
final stream = file.openRead();
await for (var chunk in stream) {
// 处理数据块
processChunk(chunk);
}
📚 参考资料
🎯 完整可运行示例代码
下面是一个整合了所有功能的完整可运行代码,包含了目录路径获取、文件操作和缓存管理的完整实现。
dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Path Provider Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF9C27B0)),
useMaterial3: true,
),
home: const HomePage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
String _appSupportDir = '';
String _appDocumentsDir = '';
String _appCacheDir = '';
String _tempDir = '';
String _lastFileContent = '';
int _cacheSize = 0;
final FileService _fileService = FileService();
@override
void initState() {
super.initState();
_loadPaths();
_loadCacheSize();
}
Future<void> _loadPaths() async {
setState(() {
_appSupportDir = '';
_appDocumentsDir = '';
_appCacheDir = '';
_tempDir = '';
});
try {
final appSupportDir = await getApplicationSupportDirectory();
final appDocumentsDir = await getApplicationDocumentsDirectory();
final appCacheDir = await getApplicationCacheDirectory();
final tempDir = await getTemporaryDirectory();
setState(() {
_appSupportDir = appSupportDir.path;
_appDocumentsDir = appDocumentsDir.path;
_appCacheDir = appCacheDir.path;
_tempDir = tempDir.path;
});
} catch (e) {
debugPrint('获取路径失败: $e');
}
}
Future<void> _loadCacheSize() async {
final size = await _fileService.getCacheSize();
setState(() {
_cacheSize = size;
});
}
Future<void> _writeFile() async {
try {
final content = 'Hello, OpenHarmony! 写入时间: ${DateTime.now()}';
await _fileService.writeFile('test.txt', content);
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件写入成功')),
);
}
} catch (e) {
debugPrint('写入文件失败: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('写入文件失败: $e')),
);
}
}
}
Future<void> _readFile() async {
try {
final content = await _fileService.readFile('test.txt');
if (content != null) {
setState(() {
_lastFileContent = content;
});
if (mounted) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text('文件内容'),
content: SingleChildScrollView(
child: Text(content),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('关闭'),
),
],
),
);
}
} else {
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件不存在')),
);
}
}
} catch (e) {
debugPrint('读取文件失败: $e');
}
}
Future<void> _deleteFile() async {
try {
await _fileService.deleteFile('test.txt');
setState(() {
_lastFileContent = '';
});
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('文件删除成功')),
);
}
} catch (e) {
debugPrint('删除文件失败: $e');
}
}
Future<void> _clearCache() async {
try {
await _fileService.clearCache();
await _loadCacheSize();
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('缓存清理成功')),
);
}
} catch (e) {
debugPrint('清理缓存失败: $e');
if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('清理缓存失败: $e')),
);
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Path Provider 完整示例'),
actions: [
IconButton(
onPressed: () {
_loadPaths();
_loadCacheSize();
},
icon: const Icon(Icons.refresh),
tooltip: '刷新',
),
],
),
body: ListView(
padding: const EdgeInsets.all(16),
children: [
const Text(
'目录路径',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
_buildPathCard(
icon: Icons.folder,
title: '应用支持目录',
subtitle: '应用专属支持文件',
path: _appSupportDir,
color: const Color(0xFF9C27B0),
),
const SizedBox(height: 12),
_buildPathCard(
icon: Icons.description,
title: '应用文档目录',
subtitle: '应用专属文档文件',
path: _appDocumentsDir,
color: const Color(0xFF6366F1),
),
const SizedBox(height: 12),
_buildPathCard(
icon: Icons.cached,
title: '应用缓存目录',
subtitle: '应用专属缓存文件',
path: _appCacheDir,
color: const Color(0xFF10B981),
),
const SizedBox(height: 12),
_buildPathCard(
icon: Icons.more_time,
title: '临时目录',
subtitle: '系统临时文件',
path: _tempDir,
color: const Color(0xFFF59E0B),
),
const SizedBox(height: 24),
const Text(
'文件操作',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildActionButton(
icon: Icons.edit_note,
label: '写入文件',
color: const Color(0xFF6366F1),
onPressed: _writeFile,
),
_buildActionButton(
icon: Icons.read_more,
label: '读取文件',
color: const Color(0xFF10B981),
onPressed: _readFile,
),
_buildActionButton(
icon: Icons.delete,
label: '删除文件',
color: const Color(0xFFEF4444),
onPressed: _deleteFile,
),
],
),
if (_lastFileContent.isNotEmpty) ...[
const SizedBox(height: 24),
const Text(
'最近读取的内容',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.w600),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: Colors.grey[100],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.grey[300]!),
),
child: Text(
_lastFileContent,
style: const TextStyle(fontFamily: 'monospace', fontSize: 12),
),
),
],
const SizedBox(height: 24),
const Text(
'缓存管理',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
Card(
elevation: 2,
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'缓存大小',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
Text(
'${(_cacheSize / 1024).toStringAsFixed(2)} KB',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: _cacheSize > 1024 * 1024
? Colors.red
: Colors.green,
),
),
],
),
const SizedBox(height: 12),
SizedBox(
width: double.infinity,
child: ElevatedButton.icon(
onPressed: _clearCache,
icon: const Icon(Icons.cleaning_services),
label: const Text('清空缓存'),
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFF59E0B),
foregroundColor: Colors.white,
padding: const EdgeInsets.symmetric(vertical: 12),
),
),
),
],
),
),
),
],
),
);
}
Widget _buildPathCard({
required IconData icon,
required String title,
required String subtitle,
required String path,
required Color color,
}) {
return Card(
elevation: 2,
child: ListTile(
leading: CircleAvatar(
backgroundColor: color.withOpacity(0.1),
child: Icon(icon, color: color),
),
title: Text(
title,
style: const TextStyle(fontWeight: FontWeight.w600),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(subtitle),
const SizedBox(height: 4),
Text(
path.isEmpty ? '加载中...' : path,
style: TextStyle(
fontSize: 12,
color: Colors.grey[600],
fontFamily: 'monospace',
),
overflow: TextOverflow.ellipsis,
),
],
),
trailing: path.isNotEmpty
? IconButton(
icon: const Icon(Icons.copy),
onPressed: () {
// 复制路径到剪贴板(需要添加 flutter/services)
},
tooltip: '复制路径',
)
: null,
),
);
}
Widget _buildActionButton({
required IconData icon,
required String label,
required Color color,
required VoidCallback onPressed,
}) {
return Column(
children: [
Container(
decoration: BoxDecoration(
color: color.withOpacity(0.1),
shape: BoxShape.circle,
),
child: IconButton(
onPressed: onPressed,
icon: Icon(icon, color: color),
iconSize: 32,
padding: const EdgeInsets.all(16),
),
),
const SizedBox(height: 8),
Text(
label,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.w500,
color: color,
),
),
],
);
}
}
/// 文件服务类 - 封装常用文件操作
class FileService {
static final FileService _instance = FileService._internal();
factory FileService() => _instance;
FileService._internal();
Directory? _cachedAppDocumentsDir;
Directory? _cachedAppCacheDir;
// 获取应用文档目录(带缓存)
Future<Directory> getAppDocumentsDir() async {
_cachedAppDocumentsDir ??= await getApplicationDocumentsDirectory();
return _cachedAppDocumentsDir!;
}
// 获取应用缓存目录(带缓存)
Future<Directory> getAppCacheDir() async {
_cachedAppCacheDir ??= await getApplicationCacheDirectory();
return _cachedAppCacheDir!;
}
// 写入文件
Future<void> writeFile(String filename, String content) async {
final dir = await getAppDocumentsDir();
// 确保目录存在
if (!await dir.exists()) {
await dir.create(recursive: true);
}
final file = File('${dir.path}/$filename');
await file.writeAsString(content);
}
// 读取文件
Future<String?> readFile(String filename) async {
final dir = await getAppDocumentsDir();
final file = File('${dir.path}/$filename');
if (await file.exists()) {
return await file.readAsString();
}
return null;
}
// 删除文件
Future<void> deleteFile(String filename) async {
final dir = await getAppDocumentsDir();
final file = File('${dir.path}/$filename');
if (await file.exists()) {
await file.delete();
}
}
// 清空缓存目录
Future<void> clearCache() async {
final dir = await getAppCacheDir();
if (await dir.exists()) {
await dir.delete(recursive: true);
}
}
// 获取缓存大小
Future<int> getCacheSize() async {
final dir = await getAppCacheDir();
if (!await dir.exists()) {
return 0;
}
int totalSize = 0;
try {
await for (final entity in dir.list(recursive: true)) {
if (entity is File) {
totalSize += await entity.length();
}
}
} catch (e) {
debugPrint('计算缓存大小失败: $e');
}
return totalSize;
}
// 检查文件是否存在
Future<bool> fileExists(String filename) async {
final dir = await getAppDocumentsDir();
final file = File('${dir.path}/$filename');
return await file.exists();
}
// 获取应用支持目录
Future<Directory> getAppSupportDir() async {
return await getApplicationSupportDirectory();
}
// 获取临时目录
Future<Directory> getTempDir() async {
return await getTemporaryDirectory();
}
}