Android存储路径探索

Tips: 复制的源码为Java代码,示例使用Kotlin编写。

内部存储

内部存储可以直接在设备的内部存储中保存文件。默认情况下,保存到内部存储的文件是应用的私有文件,其他应用(和用户)不能访问这些文件。 当用户卸载您的应用时,这些文件也会被移除。

  • 返回内部存储文件上目录的绝对路径,其中存储了当前应用程序的所有私有文件。例:/data/user/0/应用包名
    public abstract File getDataDir();

示例如下:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        val mDataFilePath = applicationContext.dataDir
        Log.e(javaClass.simpleName, mDataFilePath.path)
    }

打印输出: /data/user/0/应用包名

  • 获取当前应用在内部存储上的根目录,返回存储在内部存储上的文件目录的绝对路径。例:/data/user/0/应用包名/files
    public abstract File getFilesDir();

示例如下:

    // 获取系统存储上当前应用的根目录文件
    val mFileDir = activity!!.applicationContext.filesDir
    // 打印系统存储上当前应用的根目录地址  
    Log.e(javaClass.simpleName, "根目录:${mFileDir.path}")
    // 在系统存储上当前应用的根目录下创建文件夹
    val mRootFile = File(mFileDir, "content.txt")
    // 打印系统存储上当前应用的根目录地址 
    Log.e(javaClass.simpleName, "文件地址:${mRootFile.path}")
    
    // 此处省略调用代码......
        
    /**
     * 向文件中写入文本
     * Kotlin在扩展函数use中已经封装了关闭流,所以这里不用再调流的close()方法
     */
    private fun writeTextToFile(file: File) {
        BufferedWriter(FileWriter(file)).use {
            it.write("秦川小将")
        }
    }

    /**
     * 读取文件中的文本内容
     * Kotlin在扩展函数use中已经封装了关闭流,所以这里不用再调流的close()方法
     */
    private fun readTextInFile(file: File) {
        BufferedReader(FileReader(file)).use {
            var mLine: String
            while (true) {
                mLine = it.readLine() ?: break
                Log.e(javaClass.simpleName, mLine) 
            }
        }
    }

注: Kotlin在扩展函数use中已经封装了关闭流,所以这里不用再调流的close()方法。

打印输出如下:

根目录: /data/user/0/com.files.sample/files
文件地址:/data/user/0/com.files.sample/files/content.txt

秦川小将

  • 检索,创建需要的新目录,应用程序可以在其中放置自己的自定义数据文件。例:/data/user/0/应用包名/自定义文件目录名
    public abstract File getDir(String name, @FileMode int mode);

mode参数取值说明,如下:

Context.MODE_PRIVATE
默认的方式,创建的文件只能被本Activity所访问。

Context.MODE_WORLD_READABLE
允许所有其他应用程序对创建的文件具有读访问权限,Android API 17以后不建议使用。从Android API 24尝试使用此模式开始,将会抛出一个SecurityException异常。

Context.MODE_WORLD_WRITEABLE
允许所有其他应用程序对创建的文件具有写入权限。Android API LEVEL 17以后不建议使用。

Context.MODE_APPEND
将内容以追加的方式写到文件末尾。

示例如下:

val mFile = applicationContext.getDir("custom", Context.MODE_PRIVATE)
Log.e(javaClass.simpleName, mFile.path)

打印输出:/data/user/0/com.files.sample/app_custom

  • 返回当前应用在内部存储上的缓存目录的绝对路径。例:/data/user/0/应用包名/cache
    public abstract File getCacheDir();

示例如下:

    val mFile = applicationContext.cacheDir
    Log.e(javaClass.simpleName, mFile.path)

打印输出: /data/user/0/com.files.sample/cache

外部存储

外部存储是有可能移除的存储介质(例如 SD 卡)或不可移除存储(设备自带内存)。保存到外部存储的文件是全局可读取文件,而且,在计算机上启用 USB 大容量存储以传输文件后,可由用户对这些文件进行修改。

存储权限(Android v6.0需要动态申请)

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
	<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
1.Environment提供的存储路径
  • 系统根目录,例:/system
    public static File getRootDirectory()
  • 返回用户数据目录,例:/data
    public static File getDataDirectory()
  • 返回下载/缓存内容目录,例:/data/cache
    public static File getDownloadCacheDirectory()
  • 返回外部存储目录,例:/storage/emulated/0
    public static File getExternalStorageDirectory()

打印 /storage/emulated/0 目录下所有文件名

 	val mFiles = Environment.getExternalStorageDirectory()
    mFiles.list().forEach {
        Log.e(javaClass.simpleName, "${mFiles.path}/$it")
    }

getExternalStorageDirectory 具体输出:

/storage/emulated/0/MIUI
/storage/emulated/0/mipush
/storage/emulated/0/sogou
/storage/emulated/0/Android
/storage/emulated/0/.mn_1021243354
/storage/emulated/0/amap
/storage/emulated/0/backups
/storage/emulated/0/.dlprovider
/storage/emulated/0/.DataStorage
/storage/emulated/0/360
/storage/emulated/0/.sys.log
/storage/emulated/0/DCIM
/storage/emulated/0/miad
/storage/emulated/0/.mn_-980648280
/storage/emulated/0/MiMarket
/storage/emulated/0/data
/storage/emulated/0/mivideo
/storage/emulated/0/Download
/storage/emulated/0/com.miui.voiceassist
/storage/emulated/0/browser
/storage/emulated/0/.Rcs
/storage/emulated/0/.com.android.providers.downloads.ui
/storage/emulated/0/netease
/storage/emulated/0/Tencent
/storage/emulated/0/.UTSystemConfig
/storage/emulated/0/Pictures
/storage/emulated/0/.vivo
/storage/emulated/0/kingdid
/storage/emulated/0/FreeRun
/storage/emulated/0/fac_sources
/storage/emulated/0/wt_logs
/storage/emulated/0/JuphoonService
/storage/emulated/0/dctp
/storage/emulated/0/wlan_logs
/storage/emulated/0/did
/storage/emulated/0/.com.taobao.dp
/storage/emulated/0/baidu
/storage/emulated/0/com.netease.cloudmusic
/storage/emulated/0/.cm_restart_record
/storage/emulated/0/images
/storage/emulated/0/SmartHome
  • 获取顶级共享/外部存储目录以及指定类型目录的文件
    public static File getExternalStoragePublicDirectory(String type)

type 类型如下:

常量目录说明
Environment.DIRECTORY_MUSIC标准的音乐存放目录
Environment.DIRECTORY_PODCASTS标准的系统广播存放目录
Environment.DIRECTORY_RINGTONES标准的系统铃声存放目录
Environment.DIRECTORY_ALARMS标准的系统提醒铃声存放目录
Environment.DIRECTORY_NOTIFICATIONS标准的系统通知铃声存放目录
Environment.DIRECTORY_PICTURES标准的相册存放目录
Environment.DIRECTORY_MOVIES标准的电影存放目录
Environment.DIRECTORY_DOWNLOADS标准的下载存放目录
Environment.DIRECTORY_DCIM标准的相机拍摄照片和视频存放目录
Environment.DIRECTORY_DOCUMENTS标准的文档存放目录

对应常量值:


    public static String DIRECTORY_MUSIC = "Music";

    public static String DIRECTORY_PODCASTS = "Podcasts";

    public static String DIRECTORY_RINGTONES = "Ringtones";

    public static String DIRECTORY_ALARMS = "Alarms";

    public static String DIRECTORY_NOTIFICATIONS = "Notifications";

    public static String DIRECTORY_PICTURES = "Pictures";

    public static String DIRECTORY_MOVIES = "Movies";

    public static String DIRECTORY_DOWNLOADS = "Download";

    public static String DIRECTORY_DCIM = "DCIM";

    public static String DIRECTORY_DOCUMENTS = "Documents";
  • 获取外部存储设备的当前状态
    public static String getExternalStorageState()

返回值如下:

常量说明
Environment.MEDIA_UNKNOWN未知存储状态
Environment.MEDIA_REMOVED移除状态:SDCard成功移除
Environment.MEDIA_UNMOUNTED未挂载:识别到SDCard,但没有挂载
Environment.MEDIA_CHECKING检查状态:检查SDCard的有效性
Environment.MEDIA_NOFSNOFS状态:识别到SDCard卡,但无法挂载。无法挂载原因,可能是SDCard无存储介质,或者SDCard卡的文件系统与Android无兼容
Environment.MEDIA_MOUNTED挂载状态:SDCard卡已经成功挂载
Environment.MEDIA_MOUNTED_READ_ONLY只读状态:SDCard已经挂载,但是是只读的
Environment.MEDIA_SHARED共享状态:识别到SDCard卡,但SDCard未挂载,而是作为mass storage等设备(如以u盘的方式连接到电脑上)
Environment.MEDIA_BAD_REMOVAL非法移除状态:移除SDCard之前,没有卸载SDCard
Environment.MEDIA_UNMOUNTABLE无法挂载状态:识别到sdcard卡,但无法挂载。无法挂载的原因,可能是SDCard的存储介质部分损坏

对应常量值:

    public static final String MEDIA_UNKNOWN = "unknown";

    public static final String MEDIA_REMOVED = "removed";

    public static final String MEDIA_UNMOUNTED = "unmounted";

    public static final String MEDIA_CHECKING = "checking";

    public static final String MEDIA_NOFS = "nofs";

    public static final String MEDIA_MOUNTED = "mounted";

    public static final String MEDIA_MOUNTED_READ_ONLY = "mounted_ro";

    public static final String MEDIA_SHARED = "shared";

    public static final String MEDIA_BAD_REMOVAL = "bad_removal";

    public static final String MEDIA_UNMOUNTABLE = "unmountable";
  • 返回指定路径共享/外部存储设备的当前状态
    public static String getExternalStorageState(File path)

返回值与 static String getExternalStorageState() 一致。

  • 设备的外存是否是用内存模拟的,是则返回true
    public static boolean isExternalStorageEmulated()
  • 返回主“外部存储设备是否是可拆卸的。
    public static boolean isExternalStorageRemovable()
2.Context提供的存储路径
  • 返回设备外部存储上目录的绝对路径,应用程序可以在其中放置其拥有的永久文件。
    • 这些文件是应用程序的内部文件,通常不会作为媒体显示给用户。
    • 同时当应用被卸载时,这些文件将会被删除。
    • 例:/storage/emulated/0/Android/data/应用包名/files/type
    @Nullable
    public abstract File getExternalFilesDir(@Nullable String type);

参数type取值说明:

type取值与 getExternalStoragePublicDirectory 一样,存储路径不同。
getExternalFilesDir 存储的目录却是在 /storage/emulated/0/Android/data/应用包名/files/type

示例如下:

    val mFile = applicationContext.getExternalFilesDirs(Environment.DIRECTORY_PICTURES)
    if (mFile.isNotEmpty()){
        mFile.iterator().forEach {
            Log.e(javaClass.simpleName, it.path)
        }
    }

打印输出:/storage/emulated/0/Android/data/com.files.sample/files/Pictures

  • 应用程序如果有obb文件,则返回应用程序的obb文件的外部存储目录的绝对路径。例:/storage/emulated/0/Android/obb/应用报名
    public abstract File getObbDir();

示例如下:

    val mFile = applicationContext.obbDir
    Log.e(javaClass.simpleName, mFile.path)

打印输出:/storage/emulated/0/Android/obb/com.files.sample

  • 应用程序如果有obb文件,则返回应用程序的obb文件的外部存储目录的绝对路径的集合。通过 forEach 便利可查看全部。
    public abstract File[] getObbDirs();

示例如下:

    val mFile = applicationContext.obbDirs
    if (mFile != null && mFile.isNotEmpty()) {
        mFile.iterator().forEach {
            Log.e(javaClass.simpleName, it.path)
        }
    }

打印输出:/storage/emulated/0/Android/obb/com.files.sample

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒙同學

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值