Android 分区存储

本文详细介绍了Android系统的内部存储和外部存储,包括各自的用途、访问方法以及分区存储的影响。内部存储用于系统和应用数据,外部存储则用于更大的媒体文件。Android 4.4及以上系统将内置存储分为内部和外部存储。应用可以访问内部存储的私有目录,而外部存储分为私有和公共目录,私有目录在卸载应用时会被删除。Android 10引入的分区存储限制了对外部存储的访问,鼓励使用MediaStore API。文章还讲解了如何在不同情况下读写文件,以及如何处理权限问题。
摘要由CSDN通过智能技术生成

1.Android存储

Android存储分为内部存储和外部存储(外部存储并不是指SD存储卡或外部硬盘)。

①内部存储

用于Android系统本身和应用程序的存储区域,比如手机的/system/、/data/等目录。 如果没有这一块存储区域是无法运行Android系统和应用程序的。

其中data/data/包名/XXX是Android系统提供给app存储数据的内部存储空间,由app创建的SharedPreferences、Sqlite数据库、缓存文件等都保存在该文件夹中。该目录只能由该app自身访问,其他应用程序和用户无法访问存储在此空间中的文件,并且该目录会随着应用的卸载而被移除。

获取手机内部存储绝对路径/data的方法:

Environment.getDataDirectory().getAbsolutePath();

注意:如果手机获取到了root权限,就可以访问内部存储空间中的文件数据。

②外部存储

手机的内部存储空间通常不会很大,一旦手机的内部存储容量用完,可能会出现手机无法使用的情形。因此需要将一些比较大的媒体文件放到机身外部存储中。以前的手机中具备一个SD存储卡槽,插入SD存储卡,系统会将SD储存卡的存储空间挂载成外部存储空间。但是现在的手机已经不支持SD存储卡扩展功能了,取而代之的是手机自带了一个机身内置存储空间,这个机身存储和SD存储卡的功能是完全一样的,Android系统会将内置存储空间的一部分区域划分为内部存储,另一部分划分为外部存储,然后通过Linux文件挂载的方式将这些存储空间进行挂载。

获取手机外部存储的路径/storage/emulated/0的方法:
Environment.getExternalStorageDirectory().getAbsolutePath();

③现在很多手机自带的内置存储空间很大, 因此Android4.4系统及以上的手机将机身内置存储分为了内部存储internal和外部存储external两个不同的储存区域,用来存储不同的数据。

如果Android4.4系统及以上的手机还支持单独外接SD卡,那么外接的SD卡一定是外部存储,此时手机上是有两个外部存储空间的。为了区分这两个外部存储,google提供了getExternalFilesDirs方法,这个API可以获取多个外部存储空间,它返回一个File数组,File数组中就包含了手机自身所带的外部存储和外接SD卡所定义的外部存储了。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {

    File[] files = getExternalFilesDirs( Environment.MEDIA_MOUNTED);

    for(File file:files){

        Log.e("Environment", file.getAbsolutePath())

    }

}

注意:Android手机支持外接多个外部存储介质空间,如果用户在设备上移除了介质,则外部存储可能变为不可用状态。 所以在使用外部存储执行任何工作之前, 最好调用getExternalStorageState()来检查介质是否可用。

//判断外部存储是否可用
if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
    ...
}

b17fe52e74ea47bdb2fcdcd7f7ef1c07.png

可见,内部存储和外部存储可以是在同一块存储介质上面的,只是概念上做了区分,即内部存储和外部存储是一块存储介质上的不同区域。

 

2.Android应用存储目录

①内部存储空间中的应用私有目录

对于每一个安装的App,系统都会在内部存储空间的data/data目录下以应用包名为名字自动创建与之对应的文件夹。这个文件夹包含SharedPreferences和SQLiteDatabase持久化应用相关数据等。该文件夹是应用的私有文件夹,其他应用和用户不能访问文件夹里面的内容的(Root用户除外)。每个应用访问自己的内部存储是不需要权限的。当用户卸载该应用时,这些文件也会被移除。

1)获取当前app包名文件夹下的files文件夹路径:

context.getFilesDir().getAbsolutePath();

返回结果:data/data/packagename/files

2)获取当前app包名文件夹下cache文件夹路径:

context.getCacheDir().getAbsolutePath();

返回结果:data/data/packagename/cache

3)在内部存储空间内创建或打开现有的目录:

context.getDir("setting", MODE_PRIVATE).getAbsolutePath();

返回结果:data/data/packagename/setting

4)获取内部存储files路径下的所有文件名:

context.fileList();

5)删除内部存储files路径下的文件:

//返回true则表示删除成功

context.deleteFile(filename);

6)要在files或cache目录中创建新文件,可以使用File()构造函数,传递给File上述方法提供的指定内部存储目录的方法:

//保存内容到私有的files目录

public void save(String filename, String content) throws IOException{

    File file= new File(context.getFilesDir(), filename);

    FileOutputStream myfos= new FileOutputStream(file);

    myfos.write(content.getBytes());

    myfos.close();

}

或者读取文件:

//通过文件名来获取私有的files目录中的文件

public String get(String filename) throws IOException {

    File file= new File(context.getFilesDir(), filename);

    FileInputStream fis = new FileInputStream(file);

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    byte[] data = new byte[1024];

    int len = -1;

    while ((len = fis.read(data)) != -1) {

        baos.write(data, 0, len);

    }

    return new String(baos.toByteArray());

}

Android系统可以调用Context类中提供的openFileOutput()方法获取FileOutputStream来对文件进行操作。openFileOutput()方法接受两个参数:第一个参数是文件名,在文本创建的时候使用的就是这个名称,注意这里指定的文件名不可以包含路径(因为默认存储到/data/data//files/目录下)。第二个参数是文件的操作模式,主要有两种:MODE_PRIVATE:默认的操作模式,表示当指定同样文件名的时候,当该文件名有内容时,再次调用会覆盖原内容;MODE_APPEND:表示该文件如果已存在就往文件里面追加内容。

调用openFileOutput()获取FileOutputStream对象后就可以使用Java流的方式将数据写入到文件中了。

写入文件:

//保存内容到私有的files目录

public void save(String filename, String content) throws IOException{

    FileoutputStream myfos=context.openFileoutput(filename,Contex

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值