Flutter入门系列-文件系统

本文介绍了Flutter中如何使用path_provider插件进行文件系统操作,包括获取应用支持目录、临时目录、外部缓存目录、外部存储目录等,并展示了在各目录下进行文件读写的方法,强调了应用于不同场景的目录选择。在Android权限管理严格的背景下,建议主要使用getApplicationSupportDirectory()进行数据存储。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Flutter因为只是一个UI系统,不具备操作原生系统的能力,所以不能直接操作文件系统,因此只能借助插件来实现该功能。provider_path 是pub上使用比较多的一个插件,下面我们开始接入插件来完成相应的文件读写功能。

一、依赖

添加依赖

dependencies:
  path_provider: ^2.0.1

二、使用

1. getApplicationSupportDirectory()

在 Android 获取的是 /data/data/packagename/files 目录,等同于调用getFilesDir() 方法,而在iOS中相当于调用 NSApplicationSupportDirectory。这些目录都是程序私有的,其他程序不会访问到,适合存放一些用户信息等隐私内容。

  //创建App私有文件 /data/data/pkgname/
  //严格保密的数据,比如用户数据,建议存放在内部存储,对应 getApplicationSupportDirectory 方法。
  void createAppSupportDir() async {
    Directory dir =  await getApplicationSupportDirectory();
    log("createApplicationSupportDir ${dir.path}");
    //createApplicationSupportDir /data/user/0/com.example.flutter_widgets/files
    String filePath = "${dir.path}/hello.txt";
    File file = File(filePath);
    if (!file.existsSync()){
         file.createSync();
    }
    //向文件写入内容
    file.writeAsStringSync("Happy New Year");
    //读取文件的内容
    String data = file.readAsStringSync();
    log("readData from files $data");
  }

2. getTemporyDirectory()

在Android中是 /data/data/packagename/cache/目录,相当于调用getCacheDir()方法,在iOS中调用 NSCachesDirectory,这个目录会随机被清除,只适合存储下载文件的缓存。

  // On Android, this uses the `getCacheDir` API on the context.
  void createAppTempDir() async {
    Directory tempDir =  await getTemporaryDirectory();
    log("createAppTempDir ${tempDir.path}");
    //[log] createAppTempDir /data/user/0/com.example.flutter_widgets/cache
    String filePath = "${tempDir.path}/temp.txt";
    File file = File(filePath);
    if (!file.existsSync()){
      file.createSync();
    }
    //向文件写入内容
    file.writeAsStringSync("Happy Chinese New Year");
    //读取文件的内容
    String data = file.readAsStringSync();
    log("readData from temp files: $data");
  }

3. getExternalCacheDirectories()

在Android中,获取的是 /emulated/0/Android/Data/packagname/cache目录,相当于调用 Context.getExternalCacheDirs() 或者在API 19以下调用Context.getExternalCacheDir(),在iOS中调用会抛出异常。该目录是用指定外部缓存数据,因为手机可能存在多个外部存储卡,所以可能会有多个存储路径。

  //其余所有的数据建议存放 Android/data/包名/ ,
  //对应 getExternalCacheDirectories 和 getExternalStorageDirectories 方法。
  void createAppExternalCacheDir() async {
    List<Directory>? dirs =  await getExternalCacheDirectories();
    dirs!.forEach((subDir) {
         print("subDir $subDir");
    });
    //I/flutter (22031): subDir Directory: '/storage/emulated/0/Android/data/com.example.flutter_widgets/cache'
    //I/flutter (22031): subDir Directory: '/storage/0DEB-3D0A/Android/data/com.example.flutter_widgets/cache'
  }

4. getExternalStorageDirectory()

在Android 中,获取的是/mnt/sdcard/Android/data/packagename/files/目录,该应用程序能够访问到的最高层级的存储路径,相当于调用 getExternalFilesDir(),该方法只能在Android中使用,iOS 不能使用,会抛出异常。

  void createExternalStorageDir() async{
    Directory? dir =  await getExternalStorageDirectory();
    log("createExternalStorageDir ${dir!.path}");
    // createExternalStorageDir /storage/emulated/0/Android/data/com.example.flutter_widgets/files
    String filePath = "${dir.path}/external_store.txt";
    File file = File(filePath);
    if (!file.existsSync()){
      file.createSync();
    }
    //向文件写入内容
    file.writeAsStringSync("Happy Tiger Year");
    //读取文件的内容
    String data = file.readAsStringSync();
    ///mnt/sdcard/Android/data/com.example.flutter_widgets/files/external_store.txt
    log("readData from files $data");
  }

5. getExternalStorageDirectories()

在Android中,获取的是/mnt/sdcard/Android/data/packagename/files/目录,该函数的实现如下:

Future<List<Directory>?> getExternalStorageDirectories({
  /// Optional parameter. See [StorageDirectory] for more informations on
  /// how this type translates to Android storage directories.
  StorageDirectory? type,
}) async {
  final List<String>? paths =
      await _platform.getExternalStoragePaths(type: type);
  if (paths == null) {
    return null;
  }

  return paths.map((String path) => Directory(path)).toList();
}
enum StorageDirectory {
  /// Contains audio files that should be treated as music.
  music,
  /// Contains audio files that should be treated as podcasts.
  podcasts,
  /// Contains audio files that should be treated as ringtones.
  ringtones,
  /// Contains audio files that should be treated as alarm sounds.
  alarms,
  /// Contains audio files that should be treated as notification sounds.
  notifications,
  /// Contains images.
  pictures,
  movies,
  /// Contains files of any type that have been downloaded by the user.
  downloads,
  /// Used to hold both pictures and videos when the device filesystem is
  /// treated like a camera's.
  dcim,
  /// Holds user-created documents.
  documents,
}

 如上可以知道,该函数有可选参数能够获取存取不同内容的目录。该函数只能在Android上使用,不能在iOS平台上使用,会抛出异常。

  //存储在 /mnt/sdcard/Android/data/packagenmae/files/目录下的
  void createExternalStorageDirs() async{
   List<Directory>? dirs = await getExternalStorageDirectories();
   dirs!.forEach((element) {
      log("createExternalStorageDirs ${element.path}");
   });
   //[log] createExternalStorageDirs /storage/emulated/0/Android/data/com.example.flutter_widgets/files
   //[log] createExternalStorageDirs /storage/0DEB-3D0A/Android/data/com.example.flutter_widgets/files
  }

6. getApplicationDocumentsDirectory()

在Android中,获取的是 /data/data/packagename/app_flutter/ 目录,该目录是用存储一些用户产生的,或者一些不能被应用程序重新创建的数据,相当于调用 getDataDirectory(),如果数据是对用户可见的,那么就考虑使用 getExternalStorageDirectory() 方法,而不是该方法。在iOS中,该方法相当于调用 NSDocumentDirectory() 方法,如果数据不是用户自产生的,考虑使用 getApplicagtionSupportDirectory() 。

  //getApplicationDocumentsDirectory 是存储在 /data/data/packagename/app_flutter/ 目录下的
  void createDocumentDir() async {
    Directory dir = await  getApplicationDocumentsDirectory();
    log("createDocumentDir ${dir.path}");// createDocumentDir /data/user/0/com.example.flutter_widgets/app_flutter
    String filePath = "${dir.path}/document.txt";
    File file = File(filePath);
    if (!file.existsSync()){
      file.createSync();
    }
    //向文件写入内容
    file.writeAsStringSync("Happy Chinese New Year From Document");
    //读取文件的内容
    String data = file.readAsStringSync();
    log("readData from document files: $data path ${file.absolute.path}");
    // /data/data/com.example.flutter_widgets/app_flutter/document.txt
  }

总结:

从上面的API来看,使用最多的就是 getApplicationSupport() 目录,因为该目录兼容性比较好,可以存入用户的隐私数据,也可以存储一些其他内容数据。现在 Android 的权限管理越来越严格,基本上程序只能访问自己所能管理的目录,对于其他的目录其实没有必要去获取,比如图片和视频相册,可以依靠第三方的插件来完成即可。

参考:

Flutter 实战-文件系统目录 - 简书

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值