ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android-存储基础

2022-11-04 15:13:43  阅读:180  来源: 互联网

标签:网站 系统 解析 美元 DNS 模板 服务器 配置


前言

存储适配系列文章:

在持久化数据的时候,一般都是选择存入到文件里,本篇将着重分析Android 存储相关的知识,也是为Android 10.0 11存储适配打基础。 通过本篇文章,你将了解到:

1、存储划分 2、内部存储 3、外部存储 4、易混淆点说明

1、存储划分

Android 4.4 之前

在Android 4.4 之前,由于硬件发展受限,手机自身的存储空间有限,需要通过外置SD卡来扩展存储空间。

如上图,手机自身的存储空间,称之为机身存储,在Android 4.4 之前作为内部存储使用。当然内部存储空间一般是不够用的,所以需要通过插入外置SD卡来扩充存储空间,这当做外部存储。

Android 4.4之后

在Android 4.4 之后(含),手机机身存储扩大了:

如上图,机身存储划分为两部分:

1、内部存储 2、外部存储

当然,依然可以插入SD卡来扩充存储空间,这部分的存储空间称为扩展的外部存储空间。只是现在机身存储都比较大,很少插入SD卡了。 接下来将以Android 4.4 之后的存储划分来分析具体的存储方案。

2、内部存储

存放位置

回想一下平时使用的持久化方案:

1、SharedPreferences---->适用于存储小文件 2、数据库---->存储结构比较复杂的大文件

以上这些文件都是默认放在内部存储里。 “/” 表示根目录,内部存储里给每个应用按照其包名各自划分了目录,假设App的包名为:com.fish.myapplication 那么该文件在内部存储里的目录为: /data/user/0/com.fish.myapplication/

第一个"/“表示根目录,其后每个”/"表示目录分割符。 “0” 表示是第一个用户,后续添加了多用户则生成相应的用户目录: 如上图,新增了两个用户,生成的目录分别是:“11”、“12”。目前来说,很少开启多用户的。 一般来说,adb shell里是没有权限查看/data目录的。若要查看内部存储,通常是通过Android Studio侧边栏Device File Explorer选择对应的目标设备查看。 同样的,如果包名为:com.fish.myapplication,则对应的内部存储目录为: /data/data/com.fish.myapplication/

/data/user/0/com.fish.myapplication/ 会将值转换到/data/data/com.fish.myapplication/ 路径下。 每个App的内部存储空间仅允许自己访问(除非有更高的权限,如root),程序卸载后,该目录也会被删除。

存储内容

除了SharedPreferences、数据库文件,内部存储还存放了哪些文件呢? 为方便起见,只查看/data/data/目录下的。

刚开始有只有两个空目录。 当进行写入SharedPreferences,创建数据库、写入文件等操作后新增了几个目录:

大致介绍一下以上目录作用:

1、cache–>存放缓存文件 2、code_cache–>存放运行时代码优化等产生的缓存 3、databases–>存放数据库文件 4、files–>存放一般文件 5、shared_prefs–>存放SharedPreferences 文件 6、lib–>存放App依赖的so库 是软链接,指向/data/app/ 某个子目录下

访问方式

既然知道了各类文件存储的目录,那么如何读写这些文件呢? 我们知道在Java 的世界里,操作文件有两种方式:

字符流和字节流

以字节流为为例,一个简单的读取写入文件Demo:

//写入文件
    private void writeFile(String filePath) {
        if (TextUtils.isEmpty(filePath))
            return;

        try {
            File file = new File(filePath);
            FileOutputStream fileOutputStream = new FileOutputStream(file);
            BufferedOutputStream bos = new BufferedOutputStream(fileOutputStream);
            String writeContent = "hello world
";
            bos.write(writeContent.getBytes());
            bos.flush();
            bos.close();

        } catch (Exception e) {

        }
    }

    //从文件读取
    private void readFile(String filePath) {
        if (TextUtils.isEmpty(filePath))
            return;

        try {
            File file = new File(filePath);
            FileInputStream fileInputStream = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fileInputStream);
            byte[] readContent = new byte[1024];
            int readLen = 0;
            while (readLen != -1) {
                readLen = bis.read(readContent, 0, readContent.length);
                if (readLen > 0) {
                    String content = new String(readContent);
                    Log.d("test", "read content:" + content.substring(0, readLen));
                }
            }
            fileInputStream.close();
        } catch (Exception e) {

        }
    }

可以看出,通过FileInputStream/FileOutputStream构造函数传入File对象即可实现文件读写,而File对象的构造依赖于文件的存放路径,因此重点在于如何获取文件的路径。 分别说明各个目录下文件的读写: 1、读写files目录下文件

#Context.java
public abstract File getFilesDir();

使用方式:

private String getFilePath(Context context) {
        //获取files根目录
        File fileDir = context.getFilesDir();
        //获取文件
        File myFile = new File(fileDir, "myFile");
        return myFile.getAbsolutePath();
    }

context.getFilesDir()的结果是返回files目录:

/data/user/0/com.fish.myapplication/files/

拿到对应文件的File对象后,构造相应的输入输出流即可实现对该文件的读写。可以看出,过程虽然简单但是有点

标签:网站,系统,解析,美元,DNS,模板,服务器,配置
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有