Android-文件存储目录

参考资料:
https://www.jianshu.com/p/a34c644e3431
https://mp.weixin.qq.com/s/YNMKhqvVjmWsOzh24mDCsw
https://mp.weixin.qq.com/s/Sx4fejCDTTI7nlzDpcZfKg

在近期的app安全检测中,说的app存在胡乱操作存储卡的行为,建议将被测系统自身数据存放在系统的安装目录下。那么什么是系统的安装目录,应该怎么做?我们今天一步步来深入了解一下。

Andorid系统有五种数据持久化的方式:

android持久化方式

Android手机的存储分为:内部存储和外部储存,在Android4.4以前,手机机身存储就叫内部存储,插入的SD卡就是外部存储,但是在Android4.4以后这两个存储的定义又有了一些些变化,新的手机不再有外插SD卡的概念,采取了内置闪存(eMMC、UFS等)的方式,所以内部存储和外部存储在新的Android手机上已经在同一个硬件上了手机机身自带的存储也是外部存储,如果再插入SD卡的话也叫外部存储,不过现在也几乎没有在采用扩展卡内存这种方式来增加手机存储空间了,手机自带的外部存储足矣,除此以外还有一种公有目录存储,它返回的目录全都是共享的公有目录。同时也是造成Android手机文件存储混乱的罪魁祸首! 。

1.内部存储(Internal Storage)

内部存储位于系统中很特殊的一个位置,对于设备中每一个安装的 App,系统都会在 data/data/packagename/xxx 自动创建与之对应的文件夹。如果你想将文件存储于内部存储中,那么文件默认只能被你的应用访问到,且一个应用所创建的所有文件都在和应用包名相同的目录下。也就是说应用创建于内部存储的文件,与这个应用是关联起来的。当一个应用卸载之后,内部存储中的这些文件也被删除。对于这个内部目录,用户是无法访问的,除非获取root权限。

内部存储空间的获取都需要使用Context,当然Activity中也可以省略

1.1 context.getFileDir()

String fileDir = this.getFilesDir().getAbsolutePath();

打印:


image.png

通常对应 内部存储的路径为 data/data/packagename/files,但我的测试手机是小米,而华为和小米手机获取到的路径为:data/user/0/packagename/files。注意:/data/user/0/ 等同于 /data/data/

说明:

  • 可用于用于存放私有持久文件。
  • 非常适合用于存放app各种伴随app运行周期所需要的文件数据,它既不会因为手机存储空间不足而被清理,也不会因卸载app而遗留数据垃圾,并且它是私有的。

1.2 context.getCacheDir()

String cacheDir =  this.getCacheDir().getAbsolutePath();
image.png

通常对应内部存储的路径为:data/data/packagename/cache,但我的测试手机是小米,而华为和小米手机获取到的路径为:data/user/0/packagename/cache。该目录内的文件在设备内存不足时会优先被删除掉,所以存放在这里的文件是没有任何保障的,可能会随时丢掉。

说明:

  • 专门用于存放缓存数据。
  • 用户对app进行缓存清理的时候会清理缓存目录cache的数据,手机空间不足的时候系统也会对缓存目录内的数据进行清理。开发者仍要管理好缓存数据特别是内部存储的缓存,避免缓存数据过大。

1.3 context.getDir(String name,int mode)

代码:

String dir =this.getDir("spanner",MODE_PRIVATE).getAbsolutePath();
Log.e(TAG, "onCreate: "+dir);

打印:


image.png

说明:

  • 归类存放私有文件。
  • 在内部私有目录下会创建一个名为app_name的文件夹,mode以前是可以设置文件夹私有(MODE_PRIVATE)和公有的(MODE_WORLD_READABLE、MODE_WORLD_WRITEABLE),但目前公有的mode都已经废弃,意味着这个api创建的文件夹已经完全私有,不能再共享出去了。

2.外部存储(External Storage/ Shared Storage)

外部存储也需要通过context来获取,同时在app卸载之后,这些文件也会被删除。类似于内部存储.
外部存储并不总是可用的,因为外部存储可以移除(早期设备)或者作为USB存储设备连接到PC,访问前必须检查是否挂载(mounted):
我这里展示判断外部存储是否存在的操作代码:

   private void getExternalStotageState(){
        //获取状态
        String externalStorageState =Environment.getExternalStorageState();
        //判断是否存在
        if(externalStorageState.equals(Environment.MEDIA_MOUNTED)){
            Log.e("externalStorageState", "sd卡已经安装,可以进行相关文件操作");
        }else{
            Log.e("externalStorageState", "sd卡状态:"+externalStorageState);
        }
    }
2.1 Context.getExternalCacheDir()

代码:

   String externalCacheDir =this.getExternalCacheDir().getAbsolutePath();
    Log.e("externalCacheDir", externalCacheDir);

结果:


image.png

说明:

  • 专门用于存放缓存数据,和内部存储的getCacheDir()相似。
2.2 Context.getExternalFilesDir(String type)
  public static String DIRECTORY_MUSIC = "Music";
  String externalFileDir =this.getExternalFilesDir(DIRECTORY_MUSIC).getAbsolutePath();
   Log.e("externalFileDir", externalFileDir);

打印:


image.png

getExternalFilesDir(String type),type类型你可以根据自己存储文件的类型来定义,会响应的创建出该文件夹。

说明:

  • 归类存放公有文件
  • 如果type不为null的话在外部私有目录下创建返回一个名为type的文件夹,为null直接返回外部私有根目录。如无特别需要,个人的做法是传入Environment的DIRECTORY常量进行文件夹创建。
2.3getExternalMediaDirs()

代码:

 //获取外存媒体文件
 if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
     File[] files  =this.getExternalMediaDirs();
     for (File file : files) {
         Log.e("file_dir", file.getAbsolutePath());
     }
 }

打印:


image.png

说明:

  • 可存放共享媒体文件
  • 这个是在Android 5.0加入的api,创建和获取位于/sdcard/Android/media目录下的应用目录,该目录下的文件能够被其他应用访问和被MediaStore查询和获取

3. 公有目录

公有目录里面的文件是可以被自由访问,即文件的数据对其他应用或者用户来说都是可以访问的,当应用被卸载之后,其卸载前创建的文件仍然保留

对于公有目录上面的文件路径需要通过Environment获取

3.1 getExternalStorageDirectory()
        //SD卡外部存储路径
      String externalStoragePath =Environment.getExternalStorageDirectory().getPath();
        Log.e("externalStoragePath", externalStoragePath);

打印:


image.png
3.2 getExternalStoragePublicDirectory(String type)
 String eSPublicMusic = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC).getPath();
        Log.e("externalStoragePath共享音乐", eSPublicMusic);

结果:


image.png

说明:

  • 使用频率极高的api,返回在根目录下的名为type的文件夹,我把它分为两种用法:一种是传入Environment的DIRECTORY常量再创建子目录使用;一种是传入appPackageName或者易被识别归属的名称创建子目录使用。前者会比较通用,内容可以被各种工具app搜索发现(包括微信);后者算是私用,可以存放不跟随app生命的文件,即卸载后也可以保留。
  • Environment.DIRECTORY_DCIM是手机的相册。
  • Environment.DIRECTORY_PICTURES用于存放各种“正式的”图片,强烈建议在这里创建文件夹存放你想要被用户发现的图片,并且微信会扫描这个文件夹,让你的图片更容易分享。
  • Environment.DIRECTORY_DOWNLOADS可以用于存放app更新的apk等下载资源

4.系统存储目录

4.1getRootDirectory()

对应获取系统分区根路径:/system

4.2 getDataDirectory()

对应获取用户数据目录路径:/data

4.3 getDownloadCacheDirectory()

对应获取用户缓存目录路径:/cache,

5.清除数据和清除缓存的区别

5.1清除数据

清除数据清除的是保存在app中所有数据,就是上面提到的位于packagename下面的所有文件,包含内部存储(/data/data/packagename/)和外部存储(/storage/emulated/0/Android/data/packagename/)。当然除了SD卡上面的数据,SD卡上面的数据当app卸载之后还会存在的。

5.2清除缓存

缓存是程序运行时的临时存储空间,它可以存放从网络下载的临时图片,从用户的角度出发清除缓存对用户并没有太大的影响,但是清除缓存后用户再次使用该APP时,由于本地缓存已经被清理,所有的数据需要重新从网络上获取。为了在清除缓存的时候能够正常清除与应用相关的缓存,请将缓存文件存放在getCacheDir()或者 getExternalCacheDir()路径下。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,951评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,606评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,601评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,478评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,565评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,587评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,590评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,337评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,785评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,096评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,273评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,935评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,578评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,199评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,440评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,163评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,133评论 2 352

推荐阅读更多精彩内容