前言
在我們實際的應用開發過程中,常常會做一些本地持久化資料配置,在應用啟動時可以拿到配置去處理對應的業務邏輯。或者我們下載檔案、下載圖片等都需要通過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
主要作用是提供一種以平臺無關一致的方式訪問裝置的檔案系統,比如應用臨時目錄、文件目錄等。