老孟导读:Flutter 中获取文件路径,我们都知道使用 path_provider,但对其目录对含义不是很清楚,此文介绍 Android、iOS 系统的文件目录,不同场景下建议使用的目录。 不同的平
添加依赖
dependencies:
path_provider: ^1.6.14
flutter pub get
文件路径
Android 文件存储
内部存储
- cache 目录:对应 getTemporaryDirectory 方法,用于缓存文件,此目录随时可能被系统清除。
- files 目录:对应 getApplicationSupportDirectory 方法。
- code_cache:此目录存储 Flutter 相关代码和资源。
- flutter_engine/skia:Flutter 渲染引擎。
- flutter_guidePVWGWK/flutter_guide/build/flutter_assets:Flutter 资源文件。
- shared_prefs: SharePreferences 的默认路径。
- app_flutter:对应 getApplicationDocumentsDirectory方法。
- app_flutter/dbName:使用 sqlite 的默认路径,sqlite 也可以指定位置。
- 安全性,其他应用无法访问这些数据。
- 当应用卸载的时候,这些数据也会被删除,避免垃圾文件。
- 不需要申请额外权限。
- 存储的空间有限,此目录数据随时可能被系统清除,也可以通过 设置 中的 清除数据 可以清除此目录数据。
-
国内特色,不同手机厂商对此目录做了不同的限制,比如总体大小限制、单个应用程序所占空间大小限制、清除数据策略不同等。
外部存储
- cache:缓存目录,对应 getExternalCacheDirectories 方法。
- files:对应 getExternalStorageDirectories 方法。
- 当应用卸载的时候,这些数据也会被删除,避免垃圾文件。
- 不需要申请额外权限。
- 空间大且不会被系统清除,通过 设置 中的 清除数据 可以清除此目录数据。
- 用户可以直接对文件进行删除、导入操作。
- 所有应用程序均可访问。
- 用户可以直接对文件进行删除、导入操作。
- 需要申请读写权限。
-
SharePreferences 和 sqlite 数据建议存放在内部存储,插件已经帮我们完成了,无需手动处理。
- 严格保密的数据,比如用户数据,建议存放在内部存储,对应 getApplicationSupportDirectory 方法。
- 其余所有的数据建议存放 Android/data/包名/ ,对应 getExternalCacheDirectories 和 getExternalStorageDirectories 方法。
iOS 文件存储
- Documents:应用程序数据文件写入到这个目录下。这个目录用于存储用户数据。保存应用程序的重要数据文件和用户数据文件等。iTunes 同步时会备份该目录,对应 getApplicationDocumentsDirectory 方法。
- Library:对应 getLibraryDirectory 方法。
- Caches:保存应用程序使用时产生的支持文件、缓存文件、日志文件等,比如下载的音乐,视频,SDWebImage缓存等。对应 getTemporaryDirectory 方法。
- Preferences:包含应用程序的偏好设置文件,iCloud会备份设置信息。
- Application Support:对应 getApplicationSupportDirectory 方法。
- tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能,按照官方说法每三天清理一次缓存数据。
path_provider 使用
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
///
/// desc:
///
class PathProviderDemo extends StatefulWidget {
@override
_PathProviderDemoState createState() => _PathProviderDemoState();
}
class _PathProviderDemoState extends State<PathProviderDemo> {
Future<Directory> _tempDirectory;
Future<Directory> _appSupportDirectory;
Future<Directory> _appLibraryDirectory;
Future<Directory> _appDocumentsDirectory;
Future<Directory> _externalStorageDirectory;
Future<List<Directory>> _externalStorageDirectories;
Future<List<Directory>> _externalCacheDirectories;
Future<Directory> _downloadDirectory;
@override
void initState() {
super.initState();
setState(() {
_tempDirectory = getTemporaryDirectory();
_appSupportDirectory = getApplicationSupportDirectory();
_appLibraryDirectory = getLibraryDirectory();
_appDocumentsDirectory = getApplicationDocumentsDirectory();
_externalStorageDirectory = getExternalStorageDirectory();
_externalCacheDirectories = getExternalCacheDirectories();
_externalStorageDirectories = getExternalStorageDirectories();
_downloadDirectory = getDownloadsDirectory();
});
}
Widget _buildDirectory(
BuildContext context,AsyncSnapshot<Directory> snapshot) {
Text text = const Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
text = Text('path: ${snapshot.data.path}');
} else {
text = const Text('path unavailable');
}
}
return Padding(padding: EdgeInsets.symmetric(horizontal: 16),child: text);
}
Widget _buildDirectories(
BuildContext context,AsyncSnapshot<List<Directory>> snapshot) {
Text text = const Text('');
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
text = Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
final String combined =
snapshot.data.map((Directory d) => d.path).join(',');
text = Text('paths: $combined');
} else {
text = const Text('path unavailable');
}
}
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),child: text);
}
Widget _buildItem(String title,Future<Directory> future) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,children: [
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),child: Text(title),),FutureBuilder<Directory>(future: future,builder: _buildDirectory),],);
}
Widget _buildItem1(String title,Future<List<Directory>> future) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,FutureBuilder<List<Directory>>(
future: future,builder: _buildDirectories),);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),body: Center(
child: ListView(
itemExtent: 120,children: <Widget>[
_buildItem('getTemporaryDirectory',_tempDirectory),_buildItem('getApplicationSupportDirectory',_appSupportDirectory),_buildItem('getLibraryDirectory',_appLibraryDirectory),_buildItem(
'getApplicationDocumentsDirectory',_appDocumentsDirectory),_buildItem(
'getExternalStorageDirectory',_externalStorageDirectory),_buildItem('getDownloadsDirectory',_downloadDirectory),_buildItem1('getExternalStorageDirectories',_externalStorageDirectories),_buildItem1('getExternalCacheDirectories',_externalCacheDirectories),);
}
}