手机自带内存较小,不适合存储大量数据,一般,大量数据都会采用外部存储,如:服务器存储、SD卡存储、数据库存储等。
本文讲解在SD卡上存储数据,并实现对数据的读和写。
整体思路:静态权限声明、动态权限请求、布局、编写逻辑进行测试,找到文件所处位置
第1步:声明静态权限,外部存储的读和写权限
具体操作:在AndroidManifest.xml中增加两行配置
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> 
第2步:在onCreate回调函数中,动态请求权限
具体操作:版本是23以后,需要动态请求权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
     /*新API要求,23以后版本要求先授权,才能访问,一次授权后,后面就无需再授权*/
     requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            Toast.makeText(this, "获取权限", Toast.LENGTH_SHORT).show();
} else {
     /*旧API*/
     Toast.makeText(this, "没有权限", Toast.LENGTH_SHORT).show();
} 
第3步:设计布局
思路:两个按钮,别人实现读和写,一个输入框,实现用户输入的内容,通过写按钮,存储到SD卡对应的文件中;一个文本框,通过读按钮,实现将SD卡文件中的内容读取出来并显示
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
    <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="显示数据"/>
    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="请输入测试数据"/>
    <Button
        android:id="@+id/writeBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="写入"/>
    <Button
        android:id="@+id/readBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="读取"/>
</LinearLayout> 
第4步:逻辑文件
整体思路:声明属性、绑定组件、实现按钮监听事件、实现读和写
(1)声明属性
Button readBtn, writeBtn;
TextView textView;
EditText editText; 
(2)绑定组件
 readBtn = findViewById(R.id.readBtn);
 writeBtn = findViewById(R.id.writeBtn);
 editText = findViewById(R.id.editText);
 textView = findViewById(R.id.textView); 
(3)实现按钮监听事件
readBtn.setOnClickListener(this);
writeBtn.setOnClickListener(this); 
(4)实现读和写
public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.writeBtn) {
            /*获取SD卡目录*/
            File sdDir = getFilesDir();
            System.out.println(sdDir.toString());
            try {
                /*根据目录和文件名创建文件*/
                File file = new File(sdDir.getCanonicalPath() + "/" + FILENAME);
                /*创建RandomAccessFile对象,用于文件操作*/
                RandomAccessFile raf = new RandomAccessFile(file, "rw");
                /*将指针移动到文件末尾,表示偏移量,设置在末尾或者末尾以外的地方,才能进行写,从而改变文件长度*/
                raf.seek(file.length());
                /*将内容写入文件*/
                String writeContent = editText.getText().toString();
                raf.write(writeContent.getBytes());
                raf.close();
                Toast.makeText(this, "【保存的数据是】" + writeContent,
                        Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                e.printStackTrace();
                Toast.makeText(this, "异常咯", Toast.LENGTH_SHORT).show();
            }
        } else if (id == R.id.readBtn) {
            File sdDirRead = getFilesDir();
            try {
                FileInputStream fis = new FileInputStream(sdDirRead.getCanonicalPath() + "/" + FILENAME);
                BufferedReader br = new BufferedReader(new InputStreamReader(fis));
                StringBuilder sb = new StringBuilder();
                String line = "";
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                String readContent = sb.toString();
                textView.setText(readContent);
                Toast.makeText(this, "【读取到的数据是】" + readContent, Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } 
写操作思路:
- 先要通过getFilesDir()方法获取到SD卡目录
 - 然后根据目录和文件名创建指定的文件
 - 创建RandomAccessFile对象,用于文件操作
 - 获取用户输入的内容,并转换为指定格式,使用RandomAccessFile对象的write方法进行写入
 - 关闭文件操作
 - 处理提示信息以及展示
 
读操作思路:
- 先要通过getFilesDir()方法获取到SD卡目录
 - 通过文件输入流读取内容
 - 并将读取到的内容展示到UI界面并给与一定提示
 
需要注意的是:
Android 11以前的外存空间获取目录的方法为:
Environment.getExternalStorageDirectory() 
Android 11以后得版本获取目录的方法是:
getFilesDir(); 
第5步:测试
SD卡读写效果
第6步:找到创建的文件对应的存储位置
查看程序打印的存储路径:
/data/user/0/com.yibinu.sddemo/files 
找对应的位置





















