Skip to content

pubdev地址:https://pub.dev/packages/path_provider 不同的平台对应的文件系统是不同的,比如文件路径,这里推荐大家使用 Google 官方维护的插件 path_provider 支持的平台和版本如下: image.png

添加依赖

yaml
  # 文件读写
  path_provider: ^2.1.1

文件路径

path_provider提供了9种方法获取不同的文件路径,并且因为系统的差异,这9种方法在不同的系统获取路径是会有差异。 image.png 这9个方法分别如下,也很好理解,就是get目录含义Directory(),并且Android系统下才有外部存储的概念,所以包含单词External的三个目录是Android系统下独有的。 1个临时目录+4个应用程序相关目录+3个Android平台专有目录+1个下载文件目录

  • getTemporaryDirectory();:设备上未备份的临时目录的路径,常用来存储下载文件的缓存。
  • getApplicationDocumentsDirectory();:应用程序可能放置数据的目录的路径或应用程序无法重新创建的数据的目录路径。
  • getApplicationSupportDirectory();:应用程序可以在其中放置应用程序支持文件的目录的路径,这个文件目录不应该暴露给用户使用,可以存放一些严格保密的数据
  • getApplicationCacheDirectory();:放置应用程序缓存的目录。如果目录不存在会自动创建。
  • getLibraryDirectory();:应用程序可以存储持久文件的目录,备份文件以及对用户不可见的文件的目录路径
  • getExternalStorageDirectory();:应用程序可以访问顶级存储的目录的路径。此功能只能在Android上访问。
  • getExternalStorageDirectories(type: type);可以存储应用程序特定数据的目录的路径。 这些路径通常位于外部存储(如单独的分区或SD卡)上。 由于此功能仅在Android上可用。
  • getExternalCacheDirectories();:存储特定于应用程序的外部缓存数据的目录的路径。 这些路径通常位于外部存储(如单独的分区或SD卡)上,此功能只能在Android上访问。
  • getDownloadsDirectory();:存储下载文件的目录的路径,在Android平台下无法访问。

文件存储目录选择

android

Android的文件存储分为内部存储和外部存储 内部存储中的数据其他应用无法访问,外部存储用户可以直接对文件进行删除和导入。 内部存储的目录结构:

  • cache 目录:对应 getTemporaryDirectory 方法,用于缓存文件,此目录随时可能被系统清除。
  • files 目录:对应 getApplicationSupportDirectory 方法,用来存放应用严格保密的数据。
  • code_cache:此目录存储 Flutter 相关代码和资源
  • shared_prefs:SharePreferences(轻量级的本地存储) 的默认路径
  • app_flutter:对应 getApplicationDocumentsDirectory方法。
  • app_flutter/dbName:使用 sqlite(轻量级的关系型数据库,用于本地存储和管理应用程序的数据) 的默认路径,sqlite 也可以指定位置。

外部存储的目录结构:

  • cache:缓存目录,对应 getExternalCacheDirectories 方法。
  • files:对应 getExternalStorageDirectories 方法。

ios

iOS系统没有内外存储概念之分, iOS 对用户隐私保护非常严格,每个 iOS 应用程序都有一个单独的文件系统,而且只能在对应的文件系统中进行操作,此区域被称为沙盒。 每个应用沙盒有3个文件夹:

  • Documents:应用程序数据文件写入到这个目录下。这个目录用于存储用户数据。保存应用程序的重要数据文件和用户数据文件等。对应 getApplicationDocumentsDirectory 方法。
  • Library:对应 getLibraryDirectory 方法
  • tmp:存放临时文件,不会被备份,而且这个文件下的数据有可能随时被清除的可能,按照官方说法每三天清理一次缓存数据。

具体使用

文件夹

创建文件夹

yaml
void _createFolder() async {
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path = '${documentDir.path}${Platform.pathSeparator}flutter_study';
    //读取对应路径下的文件夹,判断是否存在
    var dir = Directory(path);
    if (dir.existsSync()) {
      debugPrint("存在");
    } else {
      //不存在才创建文件夹
      //创建文件,可选参数recursive:true表示可以创建嵌套文件夹,
      // false表示只能创建最后一级文件夹(上一级文件不存在会报错),默认false
      var resultDir = await dir.create(recursive: true);
      debugPrint("创建成功$resultDir");
    }
  }
  
  //输出
  创建成功Directory: '/data/user/0/com.example.flutter_demo/app_flutter/flutter_study'

遍历文件夹

dart
void _ergodicFolder() async{
  //获取应用程序目录
  Directory documentDir = await getApplicationDocumentsDirectory();
  //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
  String path = '${documentDir.path}${Platform.pathSeparator}';
  // 文件列表,可选参数recursive,默认值为false,只遍历当前目录;设置为true时会遍历当前目录及子目录
  Stream<FileSystemEntity> fileList=Directory(path).list();
  await for(FileSystemEntity file in fileList){
    debugPrint(file.toString());
  }

image.png 文件的类型有如下几种:

dart
String toString() => const [
        'file',
        'directory',
        'link',
        'unixDomainSock',
        'pipe',
        'notFound'
      ][_type];

遍历文件时可以判断文件类型筛选文件:

dart
void _ergodicChosenFolder() async{
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path = '${documentDir.path}${Platform.pathSeparator}';
    // 文件列表,可选参数recursive,默认值为false,只遍历当前目录;设置为true时会遍历当前目录及子目录
    Stream<FileSystemEntity> fileList=Directory(path).list();
    await for(FileSystemEntity file in fileList){
      debugPrint(file.toString());
      //获取文件类型
      FileSystemEntityType type=FileSystemEntity.typeSync(file.path);
      debugPrint(type.toString());
    }
  }

image.png

文件夹重命名

dart
void _renameFolder() async{
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path = '${documentDir.path}${Platform.pathSeparator}flutter_study';
    //读取对应路径下的文件夹,判断是否存在
    var dir = Directory(path);
    if (dir.existsSync()) {
      debugPrint("存在");
      var newName=await dir.rename('${dir.parent.absolute.path}${Platform.pathSeparator}newName');
      var newPath='${documentDir.path}${Platform.pathSeparator}$newName';
      var newDir=Directory(newPath);
      debugPrint(newDir.path);
    } else {
      //不存在才创建文件夹
      debugPrint("文件夹不存在");
    }
  }

image.png

文件夹删除

dart
void _deleteFolder() async{
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path = '${documentDir.path}${Platform.pathSeparator}newName';
    try{
      var dir = await Directory(path).delete();
      debugPrint('文件夹$dir删除成功');
    }catch(err){
      debugPrint('文件夹$path删除失败:$err');
    }
  }

image.png

文件

创建文件

dart
void _createFile() async {
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path =
        '${documentDir.path}${Platform.pathSeparator}newName${Platform.pathSeparator}text.txt';
    File file = File(path);
    if (file.existsSync()) {
      debugPrint("文件已经存在");
    } else {
      //创建文件
      var file = await File(path).create(recursive: true);
      debugPrint("文件创建成功:$file");
    }
  }

image.png

写入数据

覆盖数据写入

dart
void _overwriteFile() async {
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path =
        '${documentDir.path}${Platform.pathSeparator}newName${Platform.pathSeparator}text.txt';
    File file = File(path);
    if (file.existsSync()) {
      var res = await file.writeAsString("覆盖数据写入"); //写入字符串
      res = await file
          .writeAsBytes(const Utf8Encoder().convert("写入bytes数据")); //写入bytes数据
      debugPrint("数据写入成功:$res");
    } else {
      //文件不存在
      debugPrint("文件不存在");
    }
  }

追加数据写入

dart
void _appendWriteFile() async {
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path =
        '${documentDir.path}${Platform.pathSeparator}newName${Platform.pathSeparator}text.txt';
    File file = File(path);
    if (file.existsSync()) {
      file.openWrite(mode: FileMode.append).write("追加数据写入"); //写入字符串
      debugPrint("追加数据成功");
    } else {
      //文件不存在
      debugPrint("文件不存在");
    }
  }

读取数据

dart
void _readFile() async{
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path =
        '${documentDir.path}${Platform.pathSeparator}newName${Platform.pathSeparator}text.txt';
    File file = File(path);
    if (file.existsSync()) {
      var res = await file.readAsString(encoding: utf8);
      debugPrint("读取数据成功,内容是:$res");
    } else {
      //文件不存在
      debugPrint("文件不存在");
    }
  }

image.png

删除文件

dart
void _deleteFile() async {
    //获取应用程序目录
    Directory documentDir = await getApplicationDocumentsDirectory();
    //文件夹路径,Platform.pathSeparator是不同平台下的文件分隔符
    String path =
        '${documentDir.path}${Platform.pathSeparator}newName${Platform.pathSeparator}text.txt';
    File file = File(path);
    if (file.existsSync()) {
      file.delete();
      debugPrint("文件删除成功");
    } else {
      //文件不存在
      debugPrint("文件不存在");
    }
  }