有很多时候需要将文件保存到本地,这时候就需要用文件读写接口来实现,PathProvider
插件提供一种平台透明的方式来访问设备文件系统上的常用位置。该类当前支持两个文件系统位置:
NSTemporaryDirectory()
返回的值。在Android上,这是getCacheDir()
返回的值。NSDocumentDirectory
。在 Android 上,这是AppData
目录。在 Flutter 里实现文件读写,需要使用 path_provider
和 Dart 里的 I/O
模块,两者的职责并不一样,path_provider
是负责查找 iOS 或者 Android 下的目录文件,而 I/O 是负责文件的读写操作。
下面使用 path_provider
来查找本地的路径,首先在pubspec.xml
文件添加依赖:
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
path_provider: ^0.4.1
临时目录,文档目录,sd卡目录如下:
import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
....
class _LoadFileState extends State<LoadFile>{
@override
void initState(){
super.initState();
}
@override
Widget build(BuildContext context){
return new Scaffold(
appBar: new AppBar(
title: new Text("LoadFile"),
),
body: new Center(
child: RaisedButton(
child: Text("获取文件路径"),
//点击调用获取文件路径方法
onPressed: loadPath,
),
),
);
}
}
loadPath() async{
try{
//临时目录
var _tempDir = await getTemporaryDirectory();
//获取具体路径
String tempDirPath = _tempDir.path;
//文档目录
var _document = await getApplicationDocumentsDirectory();
String documentPath = _document.path;
//sd卡目录
var _sdCard = await getExternalStorageDirectory();
String sdCardPath = _sdCard.path;
//打印路径
print("临时目录:"+ tempDirPath);
print("文档目录:"+ documentPath);
print("sd卡目录:"+ sdCardPath);
}catch(err){
print(err);
}
}
输出结果(Android)如下:
I/flutter (19375): 临时目录:/data/user/0/com.example.loadflie/cache
I/flutter (19375): 文档目录:/data/user/0/com.example.loadflie/app_flutter
I/flutter (19375): sd卡目录:/storage/emulated/0
读取文件少不了权限的问题,在 Dart Packages
可以找到 simple_permissions
这个库来简化申请权限的步骤,按照上面说明跟着操作就可以:
上面的意思是在AndroidManifest
和Info.plist
文件下添加权限,身为Android coder
对AndroidManifest
这个文件很熟悉,这个文件是对Android
而言,而Info.plist
应该是对于iOS
而言,那下面先在Android上试试看,首先,在pubspec.yaml
上添加依赖:
simple_permissions: ^0.1.9
记得点击Packages get
命令。 接着在AndroidManifest
清单文件上添加对文件的读写权限:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
下面在手机sd card内部存储新建一个txt文件,尝试获取其内容:
import 'package:simple_permissions/simple_permissions.dart';//记得加上这句话
...
//读取文件方法
readData() async {
try {
//申请读文件的权限
var permission =
SimplePermissions.requestPermission(Permission.ReadExternalStorage);
var sdCardPath = getExternalStorageDirectory();
//当获取到路径的时候
sdCardPath.then((filePath) {
//获得读取文件权限
permission.then((permission_status) async {
//获取文件内容
var data = await File(filePath.path + "/flutter.txt").readAsString();
print(data);
});
});
} catch (e) {
print(e);
}
}
按钮点击方法改为 readData
:
child: RaisedButton(
child: Text("获取文件路径"),
onPressed: readData
),
点击按钮结果运行:
//把内容写入文件操作
writeData() async{
try {
//申请读文件的权限
var permission =
SimplePermissions.requestPermission(Permission.WriteExternalStorage);
var sdCardPath = getExternalStorageDirectory();
//当获取到路径的时候
sdCardPath.then((filePath) {
//获得读取文件权限
permission.then((permission_status) async {
//把内容写进文件
var data = await File(filePath.path + "/flutter.txt").writeAsString("点滴之行,看世界");
print(data);
});
});
} catch (e) {
print(e);
}
}
打开sd card
的flutter.txt
文件看看内容:
发现,把之前的内容覆盖了!那么如何实现所写入的内容不覆盖原来文件的内容呢?这时候需要用到append模式,很简单,把默认的FileMode mode: FileMode.write方式改为FileMode mode: FileMode.append,代码如下:
//把内容写进文件 现在以追加的方式
var data = await File(filePath.path + "/flutter.txt").writeAsString("Flutter is very good",
mode: FileMode.append);