第三方库引入实战指南 Flutter for OpenHarmony:path_provider 文件路径详解

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net


🎯 前言:为什么需要文件路径管理?

在移动应用开发中,文件路径管理是一个基础且重要的功能:

场景一 :应用需要保存用户下载的文件到合适的目录
场景二 :应用需要缓存图片、视频等媒体文件
场景三 :应用需要存储用户配置文件
场景四 :应用需要访问设备的外部存储
场景五:应用需要读写临时文件

path_provider 是解决这些需求的完美方案!它提供了一套跨平台的文件路径 API,让应用可以轻松地访问系统目录。

🚀 核心能力一览

功能特性 详细说明 OpenHarmony 支持
应用目录 获取应用专属目录
临时目录 获取临时文件目录
文档目录 获取公共文档目录
下载目录 获取公共下载目录
外部存储 访问外部存储(受限)
跨平台一致 所有平台行为一致

支持的目录类型

path_provider 支持以下目录类型:

方法 用途 Android iOS Windows macOS Linux OpenHarmony
getApplicationSupportDirectory 应用支持目录
getApplicationDocumentsDirectory 应用文档目录
getApplicationCacheDirectory 应用缓存目录
getTemporaryDirectory 临时文件目录
getExternalStorageDirectory 外部存储目录
getDownloadsDirectory 下载目录

📱 如何运行这些示例

运行步骤

  1. 创建新项目或使用现有项目
  2. 配置依赖(见下方)
  3. 配置权限(见下方)
  4. 复制示例代码到 lib/main.dart
  5. 运行应用: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,
      ),
    );
  }
}

🔑 关键点解析

  1. getApplicationSupportDirectory:获取应用支持目录,用于存储应用支持的文件
  2. getApplicationDocumentsDirectory:获取应用文档目录,用于存储用户文档
  3. getApplicationCacheDirectory:获取应用缓存目录,用于存储缓存文件
  4. 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');
    }
  }
}

🔑 关键点解析

  1. 导入 dart:io :使用 dart:io 包中的 File 类进行文件操作
  2. 文件路径拼接 :使用 ${dir.path}/filename 拼接文件路径
  3. 检查文件存在await file.exists() 检查文件是否存在
  4. 异步文件操作 :所有文件操作都是异步的,需要使用 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();
  }
}
相关推荐
2501_921930832 小时前
Flutter for OpenHarmony:第三方库实战 chewie 视频播放器UI组件详解
flutter·ui
Sun_gentle2 小时前
android studio创建flutter项目
android·flutter·android studio
Haha_bj3 小时前
Flutter——List.map()
flutter·app
LawrenceLan4 小时前
30.Flutter 零基础入门(三十):GridView 网格布局 —— 九宫格与商品列表必学
开发语言·前端·flutter·dart
fifiAmx4 小时前
Flutter 接入RevenueCat后台配置相关
flutter
不爱吃糖的程序媛4 小时前
Flutter Orientation 插件在鸿蒙平台的使用指南
flutter·华为·harmonyos
2501_921930834 小时前
Flutter for OpenHarmony:三方库引入 geocoding 地理编码详解
flutter
2501_921930834 小时前
Flutter for OpenHarmony:三方库适配 native_device_orientation 设备方向检测详解
flutter