前言
前面博主介绍讲解了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就能完全掌握文件存储,最终实现的效果如首图所示。