Flutter 文件读写---path_provider详解
前言
在我们实际的应用开发过程中,常常会做一些本地持久化数据配置,在应用启动时可以拿到配置去处理对应的业务逻辑。或者我们下载文件、下载图片等都需要通过IO
流来实现。
在我们操作文件的时候我们需要结合dart:io
库中的path_provider
,因为每个系统下文件路径不同,如果自己去实现会很麻烦,那么path_provider
就此产生。
源码及视频教程地址
path_provider介绍
path_provider
是一个Flutter
插件,主要作用是提供一种以平台无关一致的方式访问设备的文件系统,比如应用临时目录、文档目录等。而且path_provider
支持Android、iOS、Linux、MacOS、Windows。
path_provider App目录
app存储目录总共分为八种,我们来看一下他们的区别:
临时目录
临时目录的是系统可以随时清空的缓存文件夹
-
iOS对应的实现方式是
NSCachesDirectory
-
Android对应的实现方式是
getCacheDir()
文档目录
文档目录用于存储只能由该应用访问的文件,系统不会清除该目录,只有在删除应用时才会消失。
- iOS对应的实现方式是
NSDocumentDirectory
- Android对应的实现方式是
AppData
应用程序支持目录
应用程序支持目录用于不想向用户公开的文件,也就是你不想给用户看到的文件可放置在该目录中,系统不会清除该目录,只有在删除应用时才会消失。
-
iOS对应的实现方式是
NSApplicationSupportDirectory
-
Android对应的实现方式是
getFilesDir()
应用程序持久文件目录
该目录主要存储持久文件的目录,并且不会对用户公开,常用于存储数据库文件,比如sqlite.db等。
外部存储目录
主要用于获取外部存储目录,如SD卡等,但iOS不支持外部存储目录,目前只有Android才支持。
外部存储缓存目录
主要用户获取应用程序特定外部缓存数据的目录,比如从SD卡或者手机上有多个存储目录的,但iOS不支持外部存储目录,目前只有Android才支持。
外部存储目录(单独分区)
可根据类型获取外部存储目录,如SD卡、单独分区等,和外部存储目录不同在于他是获取一个目录数组。但iOS不支持外部存储目录,目前只有Android才支持。
桌面程序下载目录
主要用于存储下载文件的目录,只适用于Linux
、MacOS
、Windows
,Android
和iOS
平台无法使用。
path_provider方法和说明
方法 | 属性 | 描述 |
---|---|---|
getTemporaryDirectory() | Future<Directory> | 临时目录 |
getApplicationSupportDirectory() | Future<Directory> | 应用程序支持目录 |
getLibraryDirectory() | Future<Directory> | 应用程序持久文件目录 |
getApplicationDocumentsDirectory() | Future<Directory> | 文档目录 |
getExternalStorageDirectory() | Future<Directory> | 外部存储目录 |
getExternalCacheDirectories() | Future<List<Directory>?> | 外部存储缓存目录 |
getExternalStorageDirectories() | Future<List<Directory>?> | 外部存储目录(单独分区) |
getDownloadsDirectory() | Future<Directory?> | 桌面程序下载目录 |
path_provider基本使用
我们这里举一个简单的例子,通过path_provider
获取磁盘中的路径,把文字写入到文件中,具体步骤如下:
- 添加依赖
- 获取本地目录
- 写入数据到磁盘中
- 读取磁盘数据
第一步:添加依赖
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
path_provider: ^2.0.5
第二步:获取本地目录
虽然获取路径总共有八种,但是在实际应用开发过程中,我们经常使用的有三种,我们分别来获取这三种目录的路径,如下:
/// 获取文档目录文件
Future<File> _getLocalDocumentFile() async {
final dir = await getApplicationDocumentsDirectory();
return File('${dir.path}/str.txt');
}
/// 获取临时目录文件
Future<File> _getLocalTemporaryFile() async {
final dir = await getTemporaryDirectory();
return File('${dir.path}/str.txt');
}
/// 获取应用程序目录文件
Future<File> _getLocalSupportFile() async {
final dir = await getApplicationSupportDirectory();
return File('${dir.path}/str.txt');
}
第三步:写入数据到磁盘中
我们这里通过writeAsString()
来将name
值写入到磁盘中,如果你需要同步写入可调用writeAsStringSync()
,或者想通过字节流的方式写入可以调用writeAsBytes()
。
String name = "Jimi";
/// 写入数据
Future<void> writeString(String str) async {
final file = await _getLocalDocumentFile();
await file.writeAsString(name);
final file1 = await _getLocalTemporaryFile();
await file1.writeAsString(name);
final file2 = await _getLocalSupportFile();
await file2.writeAsString(name);
print("写入成功");
}
第四步:读取磁盘数据
这里加了一个try catch
,防止在读取文件出现异常导致崩溃,我们分别读取三个目录里面的文件并对其增加相应的打印。
/// 读取值
Future<void> readString() async {
try {
final file = await _getLocalDocumentFile();
final result = await file.readAsString();
print("result-----$result");
final file1 = await _getLocalTemporaryFile();
final result1 = await file1.readAsString();
print("result1-----$result1");
final file2 = await _getLocalSupportFile();
final result2 = await file2.readAsString();
print("result2-----$result2");
} catch (e) {
}
}
完整示例代码
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
String name = "Jimi";
/// 获取文档目录文件
Future<File> _getLocalDocumentFile() async {
final dir = await getApplicationDocumentsDirectory();
return File('${dir.path}/str.txt');
}
/// 获取临时目录文件
Future<File> _getLocalTemporaryFile() async {
final dir = await getTemporaryDirectory();
return File('${dir.path}/str.txt');
}
/// 获取应用程序目录文件
Future<File> _getLocalSupportFile() async {
final dir = await getApplicationSupportDirectory();
return File('${dir.path}/str.txt');
}
/// 读取值
Future<void> readString() async {
try {
final file = await _getLocalDocumentFile();
final result = await file.readAsString();
print("result-----$result");
final file1 = await _getLocalTemporaryFile();
final result1 = await file1.readAsString();
print("result1-----$result1");
final file2 = await _getLocalSupportFile();
final result2 = await file2.readAsString();
print("result2-----$result2");
} catch (e) {
}
}
/// 写入数据
Future<void> writeString(String str) async {
final file = await _getLocalDocumentFile();
await file.writeAsString(name);
final file1 = await _getLocalTemporaryFile();
await file1.writeAsString(name);
final file2 = await _getLocalSupportFile();
await file2.writeAsString(name);
print("写入成功");
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: Scaffold(
appBar: AppBar(title: Text("path_provider"),),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(name,
style: TextStyle(
color: Colors.pink,
fontSize: 30
),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: (){
writeString(name);
},
child: Text("存入本地目录"),
),
ElevatedButton(
onPressed: (){
readString();
},
child: Text("读取值"),
),
],
),
),
)
);
}
}
控制台输出
flutter: 写入成功
flutter: result-----Jimi
flutter: result1-----Jimi
flutter: result2-----Jimi
总结
当我们需要持久化数据或下载文件、图片或保存数据库文件我们将文件写入到磁盘中,那我们需要借助dart:io
以及path_provider
,而path_provider
主要作用是提供一种以平台无关一致的方式访问设备的文件系统,比如应用临时目录、文档目录等。