一、前言:

作为一个开发者,我们经常需要通过缓存一些文件到SD卡中,常见的方式就是,通过:

File sdCard = Environment.getExternalStorageDirectory();

获取SD卡根目录,然后自定义文件/文件名进行文件存储.这样做法的结果就是,当手机安装了大量的app时,SD卡根目录会迅速变得杂乱不堪。并且在API 6.0之后,根目录文件存储是需要用户授权的,就算你在AndroidManifest.xml中配置了存储权限,用户不授权也是写不进去了.

SD卡读写权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  • 1.
  • 2.

其实,Google已经提供了最佳的外部存储方案,那就是统一路径为:

/Android/data/< package name >/files/… (该路径通常挂载在/mnt/sdcard/下)

外部存储路径调用方法是: context.getExternalFilesDir(dir).getAbsolutePath()   //通过context调用,

参数dir为自自定义文件夹.这个方法获得的文件存储路径适用于6.0以后系统,主要AndroidManifest.xml配置读写权限了,就不需要用户再授权了.

内部存储路径调用方法是:context().getCacheDir().getAbsolutePath() //通过context调用


Android 中获取本地储存路径,有四个方法,
getCacheDir()、getFilesDir()、getExternalFilesDir()、getExternalCacheDir()。
接下来介绍下每个方法的特点以及路径地址

  • getCacheDir():/data/data/你的应用的包名/cache
  • getFilesDir():/data/data/你的应用的包名/files
  • getExternalFilesDir():SDCard/Android/data/你的应用的包名/files/
  • getExternalCacheDir():SDCard/Android/data/你的应用包名/cache/
  1. 从上文每个方法获取的路径中可以看出,getCacheDir()和getFilesDir()是获取手机自带的存储空间中的当前包文件的路径 ;
  2. getExternalFilesDir()和getExternalCacheDir()是获取手机中SD卡的存储控件中的当前包文件的路径。

使用外部存储记得加上访问权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  • 1.
  • 2.

存储区别简明示意图如下:

Android本地存储路径 Context.getExternalFilesDir()和Context.getExternalCacheDir()方法_Android



二、路径解析:

1. getCacheDir()

该目录主要用于存放缓存文件,当系统的内存存储空间紧张时,该目录下的文件会被删除掉。关于这些文件究竟会在存储空间剩余多少的情况,没有严格的标准保障。
注意:你不应该依赖系统来清理这些缓存文件,你应该对这些缓存文件占用的最大存储空间设定个最大值,比如是1M,当实际占用空间超过这个值时,你应该对这些缓存文件做相应的清理工作(prune)。

返回的路径可能会改变随着时间的推移,所以应该保存相对路径相对路径。

2. getFilesDir()
  1. openFileOutput() 方法存储的路径,跟getFilesDir() 返回的路径是同一个路径,换句话说:getFilesDir(),是获取openFileOutput() 方法的存储路径。
    返回的路径可能会改变随着时间的推移,所以应该保存相对路径相对路径
  2. 不需要任何权限也可以访问
    目录中的文件,会在卸载你的应用程序时被删除掉
3. getExternalFilesDir()

存储在SD卡中,和getFilesDir()类似;
该方法路径下系统不一定会自动删除文件,所以需要手动设置使用的大小
getExternalFilesDir()路径不一定可用,因为,sd卡可能被卸载

4. getExternalCacheDir()

存储在SD卡中,和getCacheDir类似;
该方法路径下系统不一定会自动删除文件,所以需要手动设置使用的大小
getExternalCacheDir()路径不一定可用,因为,sd卡可能被卸载

public String getDiskCacheDir(Context context) {  
    String cachePath = null;  
    if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())  
            || !Environment.isExternalStorageRemovable()) {  
        cachePath = context.getExternalCacheDir().getPath();  
    } else {  
        cachePath = context.getCacheDir().getPath();  
    }  
    return cachePath;  
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

三、代码解析:

1. 手机应用内置存储路径
  • getFilesDir().getAbsolutePath()
  • getFilesDir().getPath()
  • getCacheDir().getAbsolutePath()
  • getCacheDir().getPath()

实验代码:

String savePath5 = getFilesDir().getAbsolutePath();
String savePath6 = getFilesDir().getPath();

String savePath7 = getCacheDir().getAbsolutePath();
String savePath8 = getCacheDir().getPath();


Log.d(TAG,"save path5 --------->"+savePath5);
Log.d(TAG,"save path6 --------->"+savePath6);

Log.d(TAG,"save path7 --------->"+savePath7);
Log.d(TAG,"save path8 --------->"+savePath8);
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

打印结果:

tag:save path5 --------->/data/user/0/fxjzzyo.com.ffmpegtest/files
tag:save path6 --------->/data/user/0/fxjzzyo.com.ffmpegtest/files

tag: save path7 --------->/data/user/0/fxjzzyo.com.ffmpegtest/cache
tag: save path8 --------->/data/user/0/fxjzzyo.com.ffmpegtest/cache
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

结论:

  • getFilesDir()返回的是/data/user/0/包名/files这个文件夹,与应用的存在有关,当应用卸载时,里面的内容也同时被删除。
  • 同理,getCacheDir()返回的是/data/user/0/包名/cache这个文件夹,与应用的存在有关,当应用卸载时,里面的内容也同时被删除。
  • 另外,我这里的实验结果getAbsolutePath()和getPath()返回的路径是一样的,所以使用时不必纠结,我打算以后就用绝对路径getAbsolutePath()好了。


从Android 10开始,对于数据访问权限要求的越来越严,app对于私有目录的使用越来越多,进而对context.getExternalFilesDir()的使用也多了,下面是对应传不同参获取的返回路径:


getExternalCacheDir();

路径为:/storage/emulated/0/Android/data/<应用包名>/cache

getExternalFilesDir(null);

路径为:/storage/emulated/0/Android/data/<应用包名>/files

getExternalFilesDir("");

路径为:/storage/emulated/0/Android/data/<应用包名>/files

getExternalFilesDir(“logs”);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/logs

getExternalCacheDir(“logs/zip”);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/logs/zip

getExternalFilesDir(Environment.DIRECTORY_MUSIC);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Music

getExternalFilesDir(Environment.DIRECTORY_PODCASTS);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Podcasts

getExternalFilesDir(Environment.DIRECTORY_RINGTONES);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Ringtones

getExternalFilesDir(Environment.DIRECTORY_ALARMS);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Alarms

getExternalFilesDir(Environment.DIRECTORY_NOTIFICATIONS);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Notifications

getExternalFilesDir(Environment.DIRECTORY_PICTURES);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Pictures

getExternalFilesDir(Environment.DIRECTORY_MOVIES);

路径为:/storage/emulated/0/Android/data/<应用包名>/files/Movies

getDataDir;

路径为:/data/user/0/<应用包名>

getFilesDir;

路径为:/data/user/0/<应用包名>/files

getCacheDir;

路径为:/data/user/0/<应用包名>/cache



链接:https://www.jianshu.com/p/615ab815b66f

 https://blog.51cto.com/zhaoyanjun/3814806

 https://blog.csdn.net/losefrank/article/details/53464646