zoukankan      html  css  js  c++  java
  • Android存储小结

    转自: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

       
  • 相关阅读:
    windows server 2008服务器 做raid0
    SQL Server 2012将数据库备份到网络中的共享文件夹
    SQL Server 2012 使用警报调度数据库作业通知操作员
    Cent OS7上安装并初始化MySQL8.0.15
    nginx 跨域请求、别名路径及防盗链的配置
    ElasticSearch和Kibanna的安装与启动
    Mybatis报错:Result Maps collection already contains value for xx.xxx
    Redis的常见数据类型——String类型
    Redis安装与配置
    nginx日志切割(手动/自动)
  • 原文地址:https://www.cnblogs.com/spring87/p/4853560.html
Copyright © 2011-2022 走看看