欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
本文基于 Flutter 3.27.5 与 HarmonyOS 6.0 环境,深入讲解 path_provider 三方库在 OpenHarmony 平台的适配使用方法,带你全面掌握临时目录、应用文档目录、缓存目录、外部存储等各类文件路径的获取方式。

一、path_provider 库简介
path_provider 是 Flutter 官方提供的文件路径获取插件,用于获取设备上各种常用目录的路径。无论是临时文件、应用文档、缓存文件,还是外部存储,path_provider 都能提供统一且跨平台的路径获取方式。
path_provider 核心特点
| 特点 | 说明 |
|---|---|
| 跨平台兼容 | 支持 Android、iOS、macOS、Windows、Linux、Web、OpenHarmony |
| 统一接口 | 一套 API 适配所有平台 |
| 类型安全 | 返回 Directory 对象而非字符串 |
| 简单易用 | 直接调用函数即可获取路径 |
| 官方维护 | Flutter 官方插件,稳定可靠 |
支持的目录类型
| 目录类型 | 说明 | 适用场景 |
|---|---|---|
| 临时目录 | 系统可随时清理的临时文件 | 缓存下载文件 |
| 应用支持目录 | 应用支持文件,用户不可见 | 数据库、配置文件 |
| 应用文档目录 | 用户生成的文档文件 | 用户创建的文件 |
| 应用缓存目录 | 应用特定的缓存文件 | 图片缓存、数据缓存 |
| 外部存储目录 | 外部存储(如 SD 卡) | 大文件存储 |
| 外部缓存目录 | 外部存储上的缓存目录 | 大型缓存文件 |
| 下载目录 | 下载文件目录 | 下载管理器 |
使用场景
- 文件下载与缓存
- 数据库存储
- 图片/视频缓存
- 日志文件存储
- 用户数据持久化
- 应用配置存储
二、OpenHarmony 适配版本
2.1 环境说明
| 组件 | 版本 |
|---|---|
| Flutter | 3.27.5 |
| HarmonyOS | 6.0 |
| path_provider | 2.1.5 (OpenHarmony 适配版本) |
2.2 引入方式
在 pubspec.yaml 文件中添加以下依赖配置:
yaml
dependencies:
path_provider:
git:
url: https://atomgit.com/openharmony-sig/flutter_packages.git
path: packages/path_provider/path_provider
ref: br_path_provider-v2.1.5_ohos
说明: 必须使用 OpenHarmony 适配版本,通过
path_provider_ohos作为平台实现自动注册。不能使用官方 pub.dev 的版本,因为官方版本不包含 OpenHarmony 平台支持。
2.3 权限配置
在 OpenHarmony 平台,访问外部存储需要申请对应权限。在 ohos/entry/src/main/module.json5 中添加:
json
"requestPermissions": [
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:read_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
},
{
"name": "ohos.permission.WRITE_MEDIA",
"reason": "$string:write_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
]
在 ohos/entry/src/main/resources/base/element/string.json 中添加:
json
{
"name": "read_media_reason",
"value": "读取媒体文件"
},
{
"name": "write_media_reason",
"value": "写入媒体文件"
}
⚠️ 重要说明: 在 OpenHarmony 平台上,
READ_MEDIAIMAGE和WRITE_MEDIAIMAGE权限无法通过常规方式申请。如果需要访问媒体文件,建议使用应用沙箱路径(如getApplicationDocumentsDirectory或getTemporaryDirectory),这些路径不需要额外权限。
三、核心 API 讲解
3.1 getTemporaryDirectory - 获取临时目录
获取设备上的临时目录,该目录中的文件可能会被系统随时清理。
dart
Future<Directory> getTemporaryDirectory()
返回值: Directory 对象,表示临时目录。
说明:
- 该目录用于存储临时缓存文件
- 系统可能会在存储空间不足时清理该目录
- 不应存储重要数据
- 在 iOS/macOS 上对应
NSCachesDirectory - 在 Android 上对应
Context.getCacheDir - 在 OpenHarmony 上对应应用缓存目录
使用示例:
dart
import 'package:path_provider/path_provider.dart';
final tempDir = await getTemporaryDirectory();
print('临时目录: ${tempDir.path}');
// 创建临时文件
final tempFile = File('${tempDir.path}/temp_data.txt');
await tempFile.writeAsString('临时数据');
3.2 getApplicationSupportDirectory - 获取应用支持目录
获取应用支持文件目录,用于存储应用的支持文件。
dart
Future<Directory> getApplicationSupportDirectory()
返回值: Directory 对象,表示应用支持目录。
说明:
- 如果目录不存在,会自动创建
- 用于存储用户不可见的支持文件
- 不应存储用户数据文件
- 在 iOS/macOS 上对应
NSApplicationSupportDirectory - 在 Android 上对应 Flutter 引擎的
PathUtils.getFilesDir - 在 OpenHarmony 上对应应用文件目录
使用示例:
dart
final supportDir = await getApplicationSupportDirectory();
print('应用支持目录: ${supportDir.path}');
// 存储数据库文件
final dbFile = File('${supportDir.path}/app_database.db');
3.3 getApplicationDocumentsDirectory - 获取应用文档目录
获取应用文档目录,用于存储用户生成的数据。
dart
Future<Directory> getApplicationDocumentsDirectory()
返回值: Directory 对象,表示应用文档目录。
说明:
- 用于存储用户生成的或无法重新创建的数据
- 在 iOS/macOS 上对应
NSDocumentDirectory - 在 Android 上对应 Flutter 引擎的
PathUtils.getDataDirectory - 在 OpenHarmony 上对应应用文档目录
- 推荐用于持久化存储用户数据
使用示例:
dart
final docDir = await getApplicationDocumentsDirectory();
print('应用文档目录: ${docDir.path}');
// 存储用户文档
final userFile = File('${docDir.path}/user_document.txt');
await userFile.writeAsString('用户创建的内容');
3.4 getApplicationCacheDirectory - 获取应用缓存目录
获取应用特定的缓存目录。
dart
Future<Directory> getApplicationCacheDirectory()
返回值: Directory 对象,表示应用缓存目录。
说明:
- 如果目录不存在,会自动创建
- 用于存储应用特定的缓存文件
- 比临时目录更适合应用级缓存
- 在 OpenHarmony 上对应应用缓存目录
使用示例:
dart
final cacheDir = await getApplicationCacheDirectory();
print('应用缓存目录: ${cacheDir.path}');
// 缓存图片
final imageCache = File('${cacheDir.path}/image_001.jpg');
3.5 getLibraryDirectory - 获取库目录
获取库目录,用于存储持久化、备份且用户不可见的文件。
dart
Future<Directory> getLibraryDirectory()
返回值: Directory 对象,表示库目录。
说明:
- 在 iOS/macOS 上对应
NSApplicationSupportDirectory - 在 OpenHarmony 上不支持,会抛出
UnsupportedError - 在 Android 上也不支持
使用示例:
dart
try {
final libraryDir = await getLibraryDirectory();
print('库目录: ${libraryDir.path}');
} on UnsupportedError catch (e) {
print('当前平台不支持获取库目录: $e');
}
3.6 getExternalStorageDirectory - 获取外部存储目录
获取外部存储目录(如 SD 卡)。
dart
Future<Directory?> getExternalStorageDirectory()
返回值: Directory? 对象,表示外部存储目录,如果不可用则返回 null。
说明:
- 在 Android 上对应
getExternalFilesDir(null) - 在 OpenHarmony 上可能返回
null或外部存储路径 - 在 iOS 上不支持(应用沙箱限制)
- 需要外部存储权限
使用示例:
dart
final externalDir = await getExternalStorageDirectory();
if (externalDir != null) {
print('外部存储目录: ${externalDir.path}');
} else {
print('外部存储不可用');
}
3.7 getExternalCacheDirectories - 获取外部缓存目录列表
获取外部存储上的所有缓存目录。
dart
Future<List<Directory>?> getExternalCacheDirectories()
返回值: List<Directory>? 对象列表,表示外部缓存目录。
说明:
- 在 Android 上对应
Context.getExternalCacheDirs() - 可能返回多个目录(如内部存储和 SD 卡)
- 在 OpenHarmony 上可能返回空列表或 null
使用示例:
dart
final externalCaches = await getExternalCacheDirectories();
if (externalCaches != null && externalCaches.isNotEmpty) {
for (final dir in externalCaches) {
print('外部缓存目录: ${dir.path}');
}
}
3.8 getExternalStorageDirectories - 获取外部存储目录列表
获取外部存储上的所有数据目录。
dart
Future<List<Directory>?> getExternalStorageDirectories({
StorageDirectory? type,
})
参数说明:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| type | StorageDirectory? | 否 | null | 存储目录类型 |
返回值: List<Directory>? 对象列表,表示外部存储目录。
StorageDirectory 枚举说明:
| 值 | 说明 |
|---|---|
| music | 音乐文件目录 |
| podcasts | 播客文件目录 |
| ringtones | 铃声文件目录 |
| alarms | 闹钟声音目录 |
| notifications | 通知声音目录 |
| pictures | 图片文件目录 |
| movies | 电影文件目录 |
| downloads | 下载文件目录 |
| dcim | 相机照片目录 |
| documents | 文档文件目录 |
使用示例:
dart
// 获取图片目录
final pictureDirs = await getExternalStorageDirectories(
type: StorageDirectory.pictures,
);
if (pictureDirs != null && pictureDirs.isNotEmpty) {
print('图片目录: ${pictureDirs.first.path}');
}
// 获取下载目录
final downloadDirs = await getExternalStorageDirectories(
type: StorageDirectory.downloads,
);
3.9 getDownloadsDirectory - 获取下载目录
获取下载文件目录。
dart
Future<Directory?> getDownloadsDirectory()
返回值: Directory? 对象,表示下载目录。
说明:
- 返回的目录不一定存在,使用前应验证
- 在桌面操作系统上更常用
- 在 OpenHarmony 上可能返回
null
使用示例:
dart
final downloadsDir = await getDownloadsDirectory();
if (downloadsDir != null) {
print('下载目录: ${downloadsDir.path}');
} else {
print('下载目录不可用');
}
3.10 MissingPlatformDirectoryException 异常
当无法获取目录时抛出的异常。
dart
class MissingPlatformDirectoryException implements Exception {
final String message;
final Object? details;
}
属性说明:
| 属性 | 类型 | 说明 |
|---|---|---|
| message | String | 错误消息 |
| details | Object? | 详细信息(如平台错误对象) |
使用示例:
dart
try {
final docDir = await getApplicationDocumentsDirectory();
} on MissingPlatformDirectoryException catch (e) {
print('获取目录失败: ${e.message}');
print('详细信息: ${e.details}');
}
四、应用级别完整代码:文件管理器助手

以下是一个完整的文件管理器助手应用,包含以下功能:
- 查看所有可用目录路径
- 创建和管理文件
- 文件读写操作
- 目录浏览
- 文件大小显示
- 文件删除功能
dart
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(const FileManagerApp());
}
class FileManagerApp extends StatelessWidget {
const FileManagerApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '文件管理器助手',
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: const Color(0xFF4CAF50),
brightness: Brightness.light,
),
useMaterial3: true,
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
),
),
home: const FileManagerHomePage(),
);
}
}
class FileManagerHomePage extends StatefulWidget {
const FileManagerHomePage({super.key});
@override
State<FileManagerHomePage> createState() => _FileManagerHomePageState();
}
class _FileManagerHomePageState extends State<FileManagerHomePage> {
Map<String, Directory?> _directories = {};
List<FileItem> _currentFiles = [];
Directory? _currentDirectory;
bool _isLoading = false;
@override
void initState() {
super.initState();
_loadAllDirectories();
}
Future<void> _loadAllDirectories() async {
setState(() => _isLoading = true);
try {
final tempDir = await getTemporaryDirectory();
_directories['临时目录'] = tempDir;
} catch (e) {
_directories['临时目录'] = null;
}
try {
final supportDir = await getApplicationSupportDirectory();
_directories['应用支持目录'] = supportDir;
} catch (e) {
_directories['应用支持目录'] = null;
}
try {
final docDir = await getApplicationDocumentsDirectory();
_directories['应用文档目录'] = docDir;
} catch (e) {
_directories['应用文档目录'] = null;
}
try {
final cacheDir = await getApplicationCacheDirectory();
_directories['应用缓存目录'] = cacheDir;
} catch (e) {
_directories['应用缓存目录'] = null;
}
try {
final externalDir = await getExternalStorageDirectory();
_directories['外部存储目录'] = externalDir;
} catch (e) {
_directories['外部存储目录'] = null;
}
try {
final downloadsDir = await getDownloadsDirectory();
_directories['下载目录'] = downloadsDir;
} catch (e) {
_directories['下载目录'] = null;
}
if (mounted) {
setState(() => _isLoading = false);
}
}
Future<void> _openDirectory(Directory dir) async {
setState(() {
_currentDirectory = dir;
_isLoading = true;
});
try {
final entities = await dir.list().toList();
final files = <FileItem>[];
for (final entity in entities) {
if (entity is File) {
final stat = await entity.stat();
files.add(FileItem(
name: entity.path.split('/').last,
path: entity.path,
isDirectory: false,
size: stat.size,
modified: stat.modified,
));
} else if (entity is Directory) {
files.add(FileItem(
name: entity.path.split('/').last,
path: entity.path,
isDirectory: true,
size: 0,
modified: DateTime.now(),
));
}
}
if (mounted) {
setState(() {
_currentFiles = files;
_isLoading = false;
});
}
} catch (e) {
if (mounted) {
setState(() => _isLoading = false);
_showError('读取目录失败: $e');
}
}
}
Future<void> _createFile() async {
if (_currentDirectory == null) return;
final controller = TextEditingController();
final result = await showDialog<String>(
context: context,
builder: (context) => AlertDialog(
title: const Text('创建文件'),
content: TextField(
controller: controller,
decoration: const InputDecoration(
hintText: '输入文件名(如 test.txt)',
),
autofocus: true,
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context, controller.text),
child: const Text('创建'),
),
],
),
);
if (result != null && result.isNotEmpty) {
try {
final file = File('${_currentDirectory!.path}/$result');
await file.writeAsString('这是创建的文件内容\n创建时间: ${DateTime.now()}');
_showSuccess('文件创建成功');
_openDirectory(_currentDirectory!);
} catch (e) {
_showError('创建文件失败: $e');
}
}
}
Future<void> _createDirectory() async {
if (_currentDirectory == null) return;
final controller = TextEditingController();
final result = await showDialog<String>(
context: context,
builder: (context) => AlertDialog(
title: const Text('创建文件夹'),
content: TextField(
controller: controller,
decoration: const InputDecoration(
hintText: '输入文件夹名',
),
autofocus: true,
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context, controller.text),
child: const Text('创建'),
),
],
),
);
if (result != null && result.isNotEmpty) {
try {
final dir = Directory('${_currentDirectory!.path}/$result');
await dir.create();
_showSuccess('文件夹创建成功');
_openDirectory(_currentDirectory!);
} catch (e) {
_showError('创建文件夹失败: $e');
}
}
}
Future<void> _deleteFile(FileItem file) async {
final confirmed = await showDialog<bool>(
context: context,
builder: (context) => AlertDialog(
title: const Text('确认删除'),
content: Text('确定要删除 "${file.name}" 吗?'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text('取消'),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text('删除', style: TextStyle(color: Colors.red)),
),
],
),
);
if (confirmed == true) {
try {
if (file.isDirectory) {
await Directory(file.path).delete(recursive: true);
} else {
await File(file.path).delete();
}
_showSuccess('删除成功');
if (_currentDirectory != null) {
_openDirectory(_currentDirectory!);
}
} catch (e) {
_showError('删除失败: $e');
}
}
}
Future<void> _viewFile(FileItem file) async {
try {
final content = await File(file.path).readAsString();
if (mounted) {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text(file.name),
content: SizedBox(
width: double.maxFinite,
child: SingleChildScrollView(
child: Text(content),
),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: const Text('关闭'),
),
],
),
);
}
} catch (e) {
_showError('读取文件失败: $e');
}
}
void _showError(String message) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.red,
),
);
}
void _showSuccess(String message) {
if (!mounted) return;
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(message),
backgroundColor: Colors.green,
),
);
}
String _formatFileSize(int bytes) {
if (bytes < 1024) return '$bytes B';
if (bytes < 1024 * 1024) return '${(bytes / 1024).toStringAsFixed(1)} KB';
if (bytes < 1024 * 1024 * 1024) {
return '${(bytes / (1024 * 1024)).toStringAsFixed(1)} MB';
}
return '${(bytes / (1024 * 1024 * 1024)).toStringAsFixed(1)} GB';
}
String _formatDateTime(DateTime dt) {
return '${dt.year}-${dt.month.toString().padLeft(2, '0')}-${dt.day.toString().padLeft(2, '0')} ${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}';
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(
_currentDirectory == null
? '文件管理器助手'
: _currentDirectory!.path.split('/').last,
style: const TextStyle(fontWeight: FontWeight.bold),
),
backgroundColor: const Color(0xFF4CAF50),
foregroundColor: Colors.white,
leading: _currentDirectory != null
? IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () {
setState(() {
_currentDirectory = null;
_currentFiles = [];
});
},
)
: null,
),
body: _isLoading
? const Center(child: CircularProgressIndicator())
: _currentDirectory == null
? _buildDirectoryList()
: _buildFileList(),
floatingActionButton: _currentDirectory != null
? Row(
mainAxisSize: MainAxisSize.min,
children: [
FloatingActionButton(
heroTag: 'file',
onPressed: _createFile,
backgroundColor: const Color(0xFF4CAF50),
child: const Icon(Icons.note_add),
),
const SizedBox(width: 12),
FloatingActionButton(
heroTag: 'folder',
onPressed: _createDirectory,
backgroundColor: const Color(0xFF2196F3),
child: const Icon(Icons.create_new_folder),
),
],
)
: null,
);
}
Widget _buildDirectoryList() {
return ListView(
padding: const EdgeInsets.all(16),
children: [
const Text(
'可用目录',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
..._directories.entries.map((entry) {
final dir = entry.value;
final isAvailable = dir != null;
return Card(
margin: const EdgeInsets.only(bottom: 8),
child: ListTile(
leading: Icon(
isAvailable ? Icons.folder : Icons.folder_off,
color: isAvailable ? const Color(0xFF4CAF50) : Colors.grey,
),
title: Text(entry.key),
subtitle: Text(
isAvailable ? dir.path : '不可用',
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 12,
color: isAvailable ? null : Colors.grey,
),
),
trailing: isAvailable
? const Icon(Icons.chevron_right)
: null,
onTap: isAvailable ? () => _openDirectory(dir!) : null,
),
);
}),
],
);
}
Widget _buildFileList() {
if (_currentFiles.isEmpty) {
return const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.folder_open, size: 64, color: Colors.grey),
SizedBox(height: 16),
Text(
'目录为空',
style: TextStyle(fontSize: 16, color: Colors.grey),
),
],
),
);
}
return ListView.builder(
padding: const EdgeInsets.all(8),
itemCount: _currentFiles.length,
itemBuilder: (context, index) {
final file = _currentFiles[index];
return Card(
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
child: ListTile(
leading: Icon(
file.isDirectory ? Icons.folder : Icons.insert_drive_file,
color: file.isDirectory
? const Color(0xFFFFC107)
: const Color(0xFF2196F3),
),
title: Text(
file.name,
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
subtitle: Text(
file.isDirectory
? '文件夹'
: '${_formatFileSize(file.size)} · ${_formatDateTime(file.modified)}',
style: const TextStyle(fontSize: 12),
),
trailing: PopupMenuButton<String>(
itemBuilder: (context) => [
if (!file.isDirectory)
const PopupMenuItem(
value: 'view',
child: Row(
children: [
Icon(Icons.visibility, size: 20),
SizedBox(width: 8),
Text('查看'),
],
),
),
const PopupMenuItem(
value: 'delete',
child: Row(
children: [
Icon(Icons.delete, size: 20, color: Colors.red),
SizedBox(width: 8),
Text('删除', style: TextStyle(color: Colors.red)),
],
),
),
],
onSelected: (value) {
if (value == 'view') {
_viewFile(file);
} else if (value == 'delete') {
_deleteFile(file);
}
},
),
onTap: file.isDirectory ? () => _openDirectory(Directory(file.path)) : null,
),
);
},
);
}
}
class FileItem {
final String name;
final String path;
final bool isDirectory;
final int size;
final DateTime modified;
FileItem({
required this.name,
required this.path,
required this.isDirectory,
required this.size,
required this.modified,
});
}
五、OpenHarmony 适配要点
5.1 权限配置
在 OpenHarmony 平台,访问外部存储需要申请对应权限:
json
{
"name": "ohos.permission.READ_MEDIA",
"reason": "$string:read_media_reason",
"usedScene": {
"abilities": ["EntryAbility"],
"when": "inuse"
}
}
5.2 应用沙箱路径
⚠️ 重要:
READ_MEDIAIMAGE和WRITE_MEDIAIMAGE权限在 OpenHarmony 平台上无法通过常规方式申请。推荐使用应用沙箱路径,这些路径不需要额外权限:
dart
// 推荐:应用文档目录(持久存储)
final docDir = await getApplicationDocumentsDirectory();
// 推荐:应用缓存目录(可能被清理)
final cacheDir = await getApplicationCacheDirectory();
// 推荐:临时目录(可能被清理)
final tempDir = await getTemporaryDirectory();
5.3 目录创建
获取目录后,可能需要创建子目录:
dart
final docDir = await getApplicationDocumentsDirectory();
final photosDir = Directory('${docDir.path}/photos');
if (!await photosDir.exists()) {
await photosDir.create(recursive: true);
}
5.4 文件操作
使用 dart:io 进行文件操作:
dart
import 'dart:io';
final file = File('${docDir.path}/test.txt');
// 写入文件
await file.writeAsString('Hello World');
// 读取文件
final content = await file.readAsString();
// 删除文件
await file.delete();
// 检查文件是否存在
final exists = await file.exists();
5.5 不支持的功能
在 OpenHarmony 平台上,以下功能可能不受支持:
dart
// getLibraryDirectory 不受支持
try {
final libraryDir = await getLibraryDirectory();
} on UnsupportedError catch (e) {
print('不支持: $e');
}
// 外部存储目录可能返回 null
final externalDir = await getExternalStorageDirectory();
if (externalDir == null) {
print('外部存储不可用');
}
六、常见问题
Q1: 如何获取应用文档目录?
解决方案:
dart
final docDir = await getApplicationDocumentsDirectory();
print('文档目录: ${docDir.path}');
Q2: 临时目录和缓存目录有什么区别?
解决方案:
- 临时目录 (
getTemporaryDirectory):系统可能随时清理,适合临时文件 - 缓存目录 (
getApplicationCacheDirectory):应用特定的缓存,更适合应用级缓存
Q3: 如何创建子目录?
解决方案:
dart
final docDir = await getApplicationDocumentsDirectory();
final subDir = Directory('${docDir.path}/subfolder');
await subDir.create(recursive: true);
Q4: 如何列出目录内容?
解决方案:
dart
final dir = await getApplicationDocumentsDirectory();
final entities = await dir.list().toList();
for (final entity in entities) {
print(entity.path);
}
Q5: 如何获取文件大小?
解决方案:
dart
final file = File('${docDir.path}/test.txt');
final stat = await file.stat();
print('文件大小: ${stat.size} 字节');
Q6: 外部存储目录返回 null 怎么办?
解决方案: 使用应用沙箱目录替代:
dart
final externalDir = await getExternalStorageDirectory();
if (externalDir == null) {
// 使用应用文档目录
final docDir = await getApplicationDocumentsDirectory();
}
Q7: 如何安全地删除目录?
解决方案:
dart
final dir = Directory('${docDir.path}/temp');
if (await dir.exists()) {
await dir.delete(recursive: true);
}
Q8: 如何在应用中持久化存储数据?
解决方案: 使用应用文档目录:
dart
final docDir = await getApplicationDocumentsDirectory();
final dataFile = File('${docDir.path}/user_data.json');
await dataFile.writeAsString(jsonEncode(data));
七、总结
path_provider 是 Flutter 官方提供的文件路径获取插件,在 OpenHarmony 平台的适配已经非常成熟。通过本文的介绍,你应该已经掌握了:
- 各种目录类型的获取方式和适用场景
- getTemporaryDirectory、getApplicationDocumentsDirectory、getApplicationCacheDirectory 等核心 API
- 外部存储目录的使用方法和限制
- 完整的文件管理器助手应用实现
- OpenHarmony 平台的权限和文件存储注意事项
- 文件操作的最佳实践