转自:http://www.liaohuqiu.net/cn/posts/storage-in-android/

android系统自身自带有存储,另外也可以通过sd卡来扩充存储空间。前者好比pc中的硬盘,后者好移动硬盘。 前者空间较小,后者空间大,但后者不一定可用。 开发应用,处理本地数据存取时,可能会遇到这些问题:

  1. 需要判断sd卡是否可用: 占用过多机身内部存储,容易招致用户反感,优先将数据存放于sd卡;
  2. 应用数据存放路径,同其他应用应该保持一致,应用卸载时,清除数据:

    • 标新立异在sd卡根目录建一个目录,招致用户反感
    • 用户卸载应用后,残留目录或者数据在用户机器上,招致用户反感
  3. 需要判断两者的可用空间: sd卡存在时,可用空间反而小于机身内部存储,这时应该选用机身存储;

  4. 数据安全性,本应用数据不愿意被其他应用读写;

  5. 图片缓存等,不应该被扫描加入到用户相册等媒体库中去。

  1. 从API 19 / Andorid 4.4 / KITKAT开始,不再需要显式声明这两个权限,除非要读写其他应用的应用数据($appDataDir)

  2. 判断sd卡可用:

    /**
    * Check if the primary "external" storage device is available.
    *
    * @return
    */
    public static boolean hasSDCardMounted() {
    String state = Environment.getExternalStorageState();
    if (state != null && state.equals(Environment.MEDIA_MOUNTED)) {
    return true;
    } else {
    return false;
    }
    }

存储的用量情况

  • 根据系统用户不同,所能占用的存储空间大小也有不同


基本操作

  1. 使用外部存储,需要的权限,在AndoridManifest.xml中:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    • 在API level 9及其以上时,File对象的getFreeSpace()方法获取系统root用户可用空间;

      getUsableSpace()取非root用户可用空间

    • 当有多个存储可用时获取磁盘用量,根据当前系统情况选用合适的存储。

    • 根据系统存储用量,合理设定app所用的空间大小;运行时,也可做动态调整。

    • 在API level 9及其以上的系统,可直接调用File对象的相关方法,以下需自行计算:

      @TargetApi(VERSION_CODES.GINGERBREAD)
      public static long getUsableSpace(File path) {
      if (path == null) {
      return -1;
      }
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
      return path.getUsableSpace();
      } else {
      if (!path.exists()) {
      return 0;
      } else {
      final StatFs stats = new StatFs(path.getPath());
      return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks();
      }
      }
      }

    路径的规律

    一般地,通过Context 和 Environment相关的方法获取文件存取的路径。

    通过这两个类可获取各种路径,如图:

        ($rootDir)
    +- /data -> Environment.getDataDirectory()
    | |
    | | ($appDataDir)
    | +- data/com.srain.cube.sample
    | |
    | | ($filesDir)
    | +- files -> Context.getFilesDir() / Context.getFileStreamPath("")
    | | |
    | | +- file1 -> Context.getFileStreamPath("file1")
    | | ($cacheDir)
    | +- cache -> Context.getCacheDir()
    | |
    | +- app_$name ->(Context.getDir(String name, int mode)
    |
    | ($rootDir)
    +- /storage/sdcard0 -> Environment.getExternalStorageDirectory()
    | / Environment.getExternalStoragePublicDirectory("")
    |
    +- dir1 -> Environment.getExternalStoragePublicDirectory("dir1")
    |
    | ($appDataDir)
    +- Andorid/data/com.srain.cube.sample
    |
    | ($filesDir)
    +- files -> Context.getExternalFilesDir("")
    | |
    |   +- file1    -> Context.getExternalFilesDir("file1")
    | +- Music -> Context.getExternalFilesDir(Environment.Music);
    | +- Picture -> ... Environment.Picture
    | +- ...
    |
    | ($cacheDir)
    +- cache -> Context.getExternalCacheDir()
    |
    +- ???

    各个路径的特性

    下面介绍这些路径的特性以及使用中需要注意的细节:

    1. 根目录($rootDir):

      • 内部存储路径: /data, 通过Environment.getDataDirectory() 获取
      • 外部存储路径: /storage/sdcard0 (也有类似 /mnt/ 这样的),通过Environment.getExternalStorageDirectory()获取

          • 示例:

            Environment.getDataDirectory():
            /data Environment.getExternalStorageDirectory():
            /storage/sdcard0

        1. 应用数据目录($appDataDir)

          • 内部储存: $appDataDir = $rootDir/data/$packageName,
          • 外部存储: $appDataDir = $rootDir/Andorid/data/$packageName

          在这些目录下的数据,在app卸载之后,会被系统删除,我们应将应用的数据放于这两个目录中。


        2. 外部存储中,公开的数据目录。 这些目录将不会随着应用的删除而被系统删除,请斟酌使用:

          Environment.getExternalStorageDirectory():
          /storage/sdcard0 // 同 $rootDir
          Environment.getExternalStoragePublicDirectory(""):
          /storage/sdcard0 Environment.getExternalStoragePublicDirectory("folder1"):
          /storage/sdcard0/folder1

          应用数据目录下的目录

          一般的在$appDataDir下,会有两个目录

          1. 数据缓存:$cacheDir = $appDataDir/cache:

            • 内部存储:Context.getCacheDir(), 机身内存不足时,文件会被删除
            • 外部存储:Context.getExternalCacheDir()

              外部存储没有实时监控,当空间不足时,文件不会实时被删除,可能返回空对象

              示例:

              Context.getCacheDir():
              /data/data/com.srain.cube.sample/cache Context.getExternalCacheDir():
              /storage/sdcard0/Android/data/com.srain.cube.sample/cache
          2. 文件目录 $filesDir = $appDataDir/files:

            • 内部存储:通过Context.getFilesDir() 获取

              Context.getFileStreamPath(String name)返回以name为文件名的文件对象,name为空,则返回$filesDir 本身

              示例:

              Context.getFilesDir():
              /data/data/com.srain.cube.sample/files

          1. 相关代码:

            https://github.com/liaohuqiu/cube-sdk/blob/master/core/src/com/srain/cube/file/FileUtil.java

     

Android存储小结的更多相关文章

  1. Javascript本地存储小结

    前言 总括:详细讲述Cookie,LocalStorge,SesstionStorge的区别和用法. 人生如画,岁月如歌. 原文博客地址:Javascript本地存储小结 知乎专栏&& ...

  2. Android存储访问及目录

    Android存储访问及目录 Android的外部存储 Android支持外部存储(case-insensitive filesystem with immutable POSIX permissio ...

  3. Android存储之SQLite数据库

    Android存储之SQLite数据库数据库 创建数据库 package --; import android.content.Context; import android.database.sql ...

  4. Android存储路径你了解多少?

    在了解存储路径之前,先来看看Android QQ的文件管理界面,了解一下QQ的数据文件路径来源,到底是来源于什么地方? 手Q文件管理对应存储目录 我的文件:是指放在QQ指定目录下的文件:/tencen ...

  5. Android 存储(本地存储 SD卡存储 SharedPreference SQLite ContentProvider)

    本文出自:http://blog.csdn.net/dt235201314/article/details/73176149 源码下载欢迎Star(updating):https://github.c ...

  6. 一篇文章搞懂android存储目录结构

    前言 前两天因为开发一个app更新的功能,我将从服务器下载的apk文件放在了内部存储目录(测试手机为小米,路径为:data/user/0/packagename/files)下面,然后安装的时候一直安 ...

  7. android基础小结

    (注:此小结文档在全屏模式下观看效果最佳) 2016年3月1日,正式开始了我的android学习之路. 最最开始的,当然是学习怎样搭载环境了,然而苦逼的我在win10各种坑爹的指引下还是安装了一个星期 ...

  8. android存储方式的应用场景

    作为一个完整的应用程序,数据存储操作是必不可少的.因此,Android系统一共提供了四种数据存储方式.分别是:SharePreference.文件存储.SQLite. Content Provider ...

  9. Android开发学习——android存储

    Android的存储 内部存储空间RAM内存:运行内存,相当于电脑的内存ROM内存:存储内存,相当于电脑的硬盘外部存储空间 SD卡:相当于电脑的移动硬盘    * 2.2之前,sd卡路径:sdcard ...

随机推荐

  1. 根据反射获取属性信息并创建DataTable

    查看了一些方法之后,做了一些总结,此方法适用于传进的参数是List<T>类型, 但事先并不知道T的类型,T可以是自定义类型. public DataTable CreateDataTabl ...

  2. css层叠机制说明

    css通过建立与文档的关联而实施效果.文档结构重要性不言而喻,对于建立良好的内容索引.提高可维护性.较好的可访问性:另,利于css选择器选择.继承机制. 概要地讲,层叠机制是处理对文档上应用样式时解决 ...

  3. php设计模式笔记--总结篇

    一.引入  设计模式的一般定义不再说,只大概说一下我理解的设计模式,我理解的设计模式的主要目的是利用面向对象(类.接口等)特点,让代码更加易于扩展,易于重用,易于维护.这三个特点也就要求我们不要将太多 ...

  4. jchat:linux聊天程序2:MySQL

    该软件使用的数据库为MySQL,因为它免费.开源,在linux下几乎就是最好的选择. 首先要在mysql中root用户新建数据库并赋权给本用户: create database jchat; gran ...

  5. ListView学习小结

    ListView小结 ListView 是Android UI中十分重要的一个组件,在数据的显示上能有着十分灵活的表现,其使用也比较简单,一般包括以下几个要点: 1.  可以通过编写ListActiv ...

  6. gridview外边距

    马上注册,结交更多好友,享用更多功能,让你轻松玩转社区. 您需要 登录 才可以下载或查看,没有帐号?注册  x 本帖最后由 同舟 于 2013-9-30 11:44 编辑 最新项目需要个单行显示功能键 ...

  7. Annotation 与 HttpClient(5)--Annotation HttpClient

    Annotation HttpClient 本内容不保证正确性,如有问题请及时提出 经过前面四篇博客的铺垫,现在给出带有标记的HttpClient的实现. 1.     带标记的HttpClient的 ...

  8. CC++初学者编程教程(6) 配置WindowsXP虚拟机与VC6.0

    1.我们安装需要下列文件. 2.新建一个虚拟机. 3. 选择默认的 Vmware Work Station10.0 4. 我们选择这个WindowsXP镜像. 5. 我们复制一个WindowsXPSP ...

  9. 普林斯顿大学算法课 Algorithm Part I Week 3 排序算法复杂度 Sorting Complexity

    计算复杂度(Computational complexity):用于研究解决特定问题X的算法效率的框架 计算模型(Model of computation):可允许的操作(Allowable oper ...

  10. Python学习笔记3-文件的简单操作

    Python中的文件操作 Python中文件打操作离不开两个模块  os 和 shutil os:操作文件.目录: Python os模块包含普遍的操作系统功能.如果你希望你的程序能够与平台无关的话, ...