Android学习之路之数据存储(一)

写在前面

Android有五种主要存储方式的用法,包括

  1. SD卡文件
  2. 共享参数:SharedPreferences
  3. 数据库:SQLite
  4. Application
  5. 内容提供器:ContentProvider

下面,我们将要讲解一下SD卡文件,在讲解SD卡文件之间,我们先来看看Android的存储目录。


1. Android的存储目录

存储规则:

  1. 首先,需要明确的是,手机的存储空间一般分为两块,一块用于内部存储,另一块用于外部存储(SD卡)。早期的SD卡是可插拔式的存储芯片,而如今的手机把SD卡固化到手机内部,虽然拔不出来,但是Android仍然称之为外部存储。
  2. Android从7.0开始加强了SD卡的权限管理,即使App声明了完整的SD卡操作权限,系统仍然默认禁止该App访问外部存储。不过系统默认关闭存储其实只是关闭外部存储的公共空间外部存储的私有空间依然可以正常读写,即Android/data

1.1 内部存储

  1. 定义
    • 内部存储:是指每个app应用内部私有的存储空间, 比如SharedPreference存储的数据、Sqlite存储的数据、以及缓存数据等等都是放在内部存储空间里面。
  2. 特点:
    • 应用私有,不能被其他程序访问。
    • 随着应用的安装而创建,随着应用的卸载而删除。
    • 默认不可见(你在文件管理中看不到它)

路径形式:

/data/app/
/data/data/app包名/shared_prefs
/data/data/app包名/cache
/data/data/app包名/databases
/data/data/app包名/files

1.2 外部存储

  1. 定义
    • 即SD卡
    • 又分为:公有目录(空间)和私有目录(空间)
  2. 为什么SD卡会分公有和私有?
    • 解释:内部存储保存着每个应用的安装目录,但是安装目录的空间是很紧张的,所以Android在SD卡的“Android/data”目录下给每个应用又单独建了一个文件目录,用于给应用保存自己需要处理的临时文件
    • 这个给每个应用单独建立的文件目录,只有当前应用才能够读写文件,其他应用是不允许进行读写的,故而“Android/data”目录算是外部存储上的私有空间。
      另外,
公有空间私有空间
所有应用均可访问只有应用自己才可以访问
默认情况下是不存在的,需要程序员自行创建

2. 内部存储文件操作→Context

获取手机的内部存储信息通过Context类实现

方法路径
getDataDir/data/data/0/app包名
getFilesDir/data/data/app包名/files
getCacheDir/data/data/0/app包名/cache
getSharedPreferences() /data/data/app包名/shared_prefs目录

注意: /data/data/在其它手机有可能为/data/user/等目录

3. 外部存储文件操作→(SD卡)

3.1 公共空间(目录)操作→Environment

获取手机上的SD卡信息通过Environment类实现,该类是App获取各种目录信息的工具;

获取系统存储目录

  • getRootDirectory:获得系统根目录的路径。/system
  • getDataDirectory:获得系统数据目录的路径。/data
  • getDownloadCacheDirectory:获得下载缓存目录的路径。/cache

获取外部存储(SD Card)的公共空间

  • getExternalStorageState:获得SD卡的状态。其状态包括:
常量解释:返回getExternalStorageState()
MEDIA_BAD_REMOVALSDCard 被卸载前己被移除
MEDIA_CHECKING正在检查存储媒体
MEDIA_MOUNTED SD Card存在,且具有读/写权限
MEDIA_MOUNTED_READ_ONLY SD Card权限为只读
MEDIA_NOFS 不支持的文件系统(SD卡格式不对)
MEDIA_REMOVED SDCard已经移除
MEDIA_SHARED 当期 SDCard 未安装 ,但可通过 USB 存储共享
MEDIA_UNMOUNTABLE SDCard 无法安装
MEDIA_UNMOUNTED 返回 SDCard 已卸掉假设 SDCard 是存在可是没有被安装
  • getExternalStoragePublicDirectory:获得SD卡指定类型目录的路径。
Environment类的目录类型常量值常量说明
DIRECTORY_DCIMDCIM相片存放目录(包括相机拍摄的图片和视频)
DIRECTORY_DOCUMENTSDocuments文档存放目录
DIRECTORY_DOWNLOADSDownload下载文件存放目录
DIRECTORY_MOVIESMovies视频存放目录
DIRECTORY_MUSICMusic音乐存放目录
DIRECTORY_PICTURESPictures图片存放目录
  • getStorageState:获得指定目录的状态
  • getExternalStorageDirectory:获得外部存储(SD卡)的根路径。 /storage/emulated/0/
  // 获取系统的公共存储路径
  String publicPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString();
系统的公共存储路径:/storage/emulated/0/Download

3.2 私有空间(目录)操作→Context

上面我们讲过了使用Context来获取内部存储,下面我们将讲解如何使用Context来获取外部存储的私有空间

  // 获取当前App的私有存储路径
  String privatePath = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString();
当前App的私有存储路径:/storage/emulated/0/Android/data/com.example.storage/files/Download

获取外部存储(SD Card)的私有空间

方法路径
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
getExternalFilesDir(“logs/zip”)/storage/emulated/0/Android/data/<应用包名>/files/logs/zip
getExternalFilesDir()路径
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

4 StatFs 类

  • StatFs 一个模拟linux的df命令的一个类,获得SD卡和手机内存的使用情况

4.1 StatFs 常用方法:

  1. getAvailableBlocks()
    • 解释:返回 Int 。获取当前可用的存储空间
  2. getBlockCount()
    • 解释:返回 Int ,获取该区域可用的文件系统数
  3. getBlockSize()
    • 解释:返回 Int ,大小,以字节为单位,一个文件系统
  4. getFreeBlocks()
    • 解释:返回 Int ,该块区域剩余的空间
  5. restat(String path)
    • 解释:运行一个由该对象所引用的文件系统

4.2 工具类

在存储文件时,为了保证有充足的剩余空间大小,通常须要知道系统内部或者sdcard的存储大小。以下提供一个工具类

package com.neverno.util;  
import java.io.File;  
import android.os.Environment;  
import android.os.StatFs;  
public class MemoryStatus {  
    static final int ERROR = -1;    

     // 外部存储是否可用  
    static public boolean externalMemoryAvailable() {  
        return android.os.Environment.getExternalStorageState().equals(  
                android.os.Environment.MEDIA\_MOUNTED);  
    }  

     // 获取手机内部可用空间大小  
    static public long getAvailableInternalMemorySize() {  
        File path = Environment.getDataDirectory();  
        StatFs stat = new StatFs(path.getPath());  
        long blockSize = stat.getBlockSize();  
        long availableBlocks = stat.getAvailableBlocks();  
        return availableBlocks \* blockSize;  
    }  
 
     // 获取手机内部空间大小
    static public long getTotalInternalMemorySize() {  
        File path = Environment.getDataDirectory();  
        StatFs stat = new StatFs(path.getPath());  
        long blockSize = stat.getBlockSize();  
        long totalBlocks = stat.getBlockCount();  
        return totalBlocks \* blockSize;  
    } 
     
    // 获取手机外部可用空间大小  
    static public long getAvailableExternalMemorySize() {  
        if (externalMemoryAvailable()) {  
            File path = Environment.getExternalStorageDirectory();  
            StatFs stat = new StatFs(path.getPath());  
            long blockSize = stat.getBlockSize();  
            long availableBlocks = stat.getAvailableBlocks();  
            return availableBlocks \* blockSize;  
        } else {  
            return ERROR;  
        }  
    }  

    // 获取手机外部空间大小  
    static public long getTotalExternalMemorySize() {  
        if (externalMemoryAvailable()) {  
            File path = Environment.getExternalStorageDirectory();  
            StatFs stat = new StatFs(path.getPath());  
            long blockSize = stat.getBlockSize();  
            long totalBlocks = stat.getBlockCount();  
            return totalBlocks \* blockSize;  
        } else {  
            return ERROR;  
        }  
    }    
  
    static public String formatSize(long size) {  
        String suffix = null;  
        if (size >= 1024) {  
            suffix = "KiB";  
            size /= 1024;  
            if (size >= 1024) {  
                suffix = "MiB";  
                size /= 1024;  
            }  
        }  
  
        StringBuilder resultBuffer = new StringBuilder(Long.toString(size));  
        int commaOffset = resultBuffer.length() - 3;  
        while (commaOffset > 0) {  
            resultBuffer.insert(commaOffset, ',');  
            commaOffset -= 3;  
        }  
        if (suffix != null)  
            resultBuffer.append(suffix);  
        return resultBuffer.toString();  
    }  
}

5. 小结

最后,一幅图来简单说明一下Android的存储目录和获取方法
在这里插入图片描述

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值