且夫枉尺而直尋者,以利言也。如以利,則枉尋直尺而利,亦可爲與?
前言
前面博主介紹講解了key-value形式的SharedPreferences的存儲方式和sqflite的數據庫插件的使用方式,對於手機端來說,我們還需要對文件形式的存儲有一定了解。
在Flutter中已經實現了文件操作相關的API。Flutter中使用File獲取手機中的存儲目錄,它根據不同的路徑創建不同的文件。這一點與前面的持久化方式類似,都是通過插件實現的,在Flutter開發中,常用的文件存儲插件爲path_provider,下面我們來講解它的用法。
path_provider
既然是插件,我們需要在Flutter項目中引入插件,所以在pubspec.yaml文件添加如下代碼:
dependencies:
flutter:
sdk: flutter
shared_preferences: ^0.5.1+1
sqflite: ^1.1.3
path_provider: ^0.5.0+1//文件存儲引入
獲取臨時目錄
話不多說,直接上代碼:
/***
* 獲取臨時目錄
*/
_getTempDirectory() async{
Directory directory=await getTemporaryDirectory();
print(directory.path);
}
代碼很簡單就兩行代碼,首先獲取Directory,然後輸入路徑即可,臨時目錄的結果如下圖所示:
可以看到臨時目錄在應用程序包下的cache目錄中。
獲取應用文檔目錄
代碼如下:
/***
* 獲取應用文檔目錄
*/
_getAppDocDirectory() async{
Directory directory=await getApplicationDocumentsDirectory();
print(directory.path);
}
同樣,也只需要一段代碼即可,應用文檔目錄如下圖所示:
獲取外部存儲目錄
代碼如下:
/***
* 獲取外部存儲目錄
*/
_getSDCardDirectory() async{
Directory directory=await getExternalStorageDirectory();
print(directory.path);
}
輸入的外部存儲目錄的文件路徑如下:
特別注意:雖然在Android手機上有外部存儲概念,但是在IOS平臺上沒有外部存儲目錄的概念,這一點在實際開發中需要額外注意。
實戰備忘錄
講解了如果操作文件後,我們這裏通過一個備忘錄項目,讓大家熟悉的掌握文件存儲的具體操作,首先,我們需要打包操作文件存儲的類,讓便後續調用,代碼如下:
class FileHelpers{
/***
* 獲取應用文檔路徑
*/
Future<String> get _localPath async{
final directory=await getApplicationDocumentsDirectory();
return directory.path;
}
/***
* 返回應用文檔路徑File
*/
Future<File> get _localFile async{
final path=await _localPath;
return new File('$path/beiwanglu.txt');
}
/***
* 讀取文件中的數據
*/
Future<String> readFile() async{
try{
final file=await _localFile;
String data=await file.readAsString();
print(data);
return data;
}catch(e){
return "error";
}
}
/***
* 將文字存儲到文件中
*/
Future<File> writeFile(String data) async{
final file=await _localFile;
return file.writeAsString(data);
}
}
讀寫都是通過readAsString以及writeAsString操作,其他的代碼都有備註,這裏就不在贅述了,下面開始設計我們的備忘錄存儲界面,代碼如下:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: '存儲文件'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
/***
* 獲取臨時目錄
*/
_getTempDirectory() async{
Directory directory=await getTemporaryDirectory();
print(directory.path);
}
/***
* 獲取應用文檔目錄
*/
_getAppDocDirectory() async{
Directory directory=await getApplicationDocumentsDirectory();
print(directory.path);
}
/***
* 獲取外部存儲目錄
*/
_getSDCardDirectory() async{
Directory directory=await getExternalStorageDirectory();
print(directory.path);
}
final TextEditingController textEditingController=new TextEditingController();
String _data;
FileHelpers fileHelpers=new FileHelpers();
@override
void initState() {
super.initState();
fileHelpers.readFile().then((String data){
setState(() {
_data=data;
});
});
}
/***
* 存儲數據
*/
Future<File> _saveData() async{
setState(() {
_data=textEditingController.text;
});
return fileHelpers.writeFile(_data);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text('獲取臨時目錄'),
onPressed: _getTempDirectory,
),
RaisedButton(
child: Text('獲取應用文檔目錄'),
onPressed: _getAppDocDirectory,
),
RaisedButton(
child: Text('獲取外部存儲目錄'),
onPressed: _getSDCardDirectory,
),
TextField(
controller: textEditingController,
autofocus: true,
decoration: new InputDecoration(hintText: '請輸入備忘錄保存數據'),
),
RaisedButton(
child: Text('保存備忘錄數據'),
onPressed: _saveData,
),
Text(
_data ?? ''
),
],
),
),
);
}
}
界面除了一些簡單的控件之外,沒有特別需要主要的,本博文主要的文件存儲代碼在FileHelpers裏面,掌握了FileHelpers就能完全掌握文件存儲,最終實現的效果如首圖所示。