Android开发笔记(二十二)——数据存储之文件存储

文件存储是利用Java的I/O流来实现向Android硬件磁盘上进行读写的操作。

Android存储概念

内部存储 Internal Storage :不可更改的,随着应用的卸载被删除

内部存储的特点:

  • 默认只能被创建它的应用访问到
  • 当这个应用卸载后,内部存储中的文件也被删除
  • 一旦内部存储空间耗尽,手机也就无法使用

/data/data/<applicationId>/shard_prefs

/data/data/<applicationId>/databases

/data/data/<applicationId>/files

/data/data/<applicationId>/cache

这四个文件夹都是属于内部存储。

前两个文件是通过系统提供的类和方法来获得文件的内容。

后两个文件是通过 context.getCacheDir()context.getFilesDir() 这两个方法来得到。

外部存储 External Storage :可更改的。分为公有目录和私有目录,

公有目录:通过 Environment.getExternalStoragePublicDirectory(int type) 方法来获得公有目录下对应类型的文件。

私有目录:随着应用的卸载被删除
/mnt/sdcard/data/data/<applicationId>/files

/mnt/sdcard/data/data/<applicationId>/cache

File内部存储

比较重要的两个类: FileOutputStreamFileInputStream

代码示例
FileActivity的java文件:

public class FileActivity extends AppCompatActivity {

    private EditText mEtName;
    private Button mBtnSave,mBtnShow;
    private TextView mTvContent;

    private final String mFinalName = "text.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file);

        mEtName=findViewById(R.id.et_name);
        mBtnSave=findViewById(R.id.btn_save);
        mBtnShow=findViewById(R.id.btn_show);
        mTvContent=findViewById(R.id.tv_content);



        mBtnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                save(mEtName.getText().toString().trim()); //trim()表示去除前后空格,没有也可以
            }
        });

        mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTvContent.setText(read());
            }
        });
    }

    //存储数据
    private void save(String content){
        FileOutputStream fileOutputStream=null;
        try {
            //创建存储目标
            fileOutputStream = openFileOutput(mFinalName,MODE_PRIVATE);
            //字节方式存储方法
            fileOutputStream.write(content.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (fileOutputStream!=null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读取数据
    private String read(){
        FileInputStream fileInputStream = null;
        try {
            //获取读取文件
            fileInputStream = openFileInput(mFinalName);
            //设置一次读取字节数
            byte[] buff = new  byte[1024];
            //获取StringBuilder,实现字符串拼接
            StringBuilder sb = new StringBuilder("");
            int len = 0;
            //循环读取
            while ((len = fileInputStream.read(buff)) > 0){
                sb.append(new String(buff,0,len));
            }
            //返回读取数据
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if (fileInputStream!=null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="15dp">
    <EditText
        android:id="@+id/et_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="输入内容"
        />
    <Button
        android:id="@+id/btn_save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="保存"
        android:layout_marginTop="10dp"
        />
    <Button
        android:id="@+id/btn_show"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="显示"
        android:layout_marginTop="10dp"
        />
    <TextView
        android:id="@+id/tv_content"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        />
</LinearLayout>

运行效果

总结

存储数据:

  • 获取FileOutputStream对象
  • 调用write()方法
  • 调用close()方法

读取数据:

  • 获取FileInputStream对象
  • 调用read()方法
  • 调用close()方法

File外部存储

在SD中新建一个文件夹,在这个文件夹中新建一个文件,然后写入一些内容再读取出来。

和内部存储原理是相同的,就是存储路径不同,一个在内部存储器上,一个在外部存储器。

代码示例

public class FileActivity extends AppCompatActivity {

    private EditText mEtName;
    private Button mBtnSave,mBtnShow;
    private TextView mTvContent;

    private final String mFinalName = "text.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_file);

        mEtName=findViewById(R.id.et_name);
        mBtnSave=findViewById(R.id.btn_save);
        mBtnShow=findViewById(R.id.btn_show);
        mTvContent=findViewById(R.id.tv_content);



        mBtnSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                save(mEtName.getText().toString().trim()); //trim()表示去除前后空格
            }
        });

        mBtnShow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mTvContent.setText(read());
            }
        });
    }

    //存储数据
    private void save(String content){
        FileOutputStream fileOutputStream=null;
        try {
//            //外部存储
//            fileOutputStream = openFileOutput(mFinalName,MODE_PRIVATE);
            //内部存储
            //创建文件夹
            File dir = new File(Environment.getExternalStorageState(),"FileStorage");
            if (!dir.exists()) {
                dir.mkdirs();
            }
            //创建文件
            File file = new File(dir,mFinalName);
            if (!file.exists()) {
                file.createNewFile();
            }
            fileOutputStream = new FileOutputStream(file);
            fileOutputStream.write(content.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream!=null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //读取数据
    private String read(){
        FileInputStream fileInputStream = null;
        try {
//            //内部存储
//            fileInputStream = openFileInput(mFinalName);
            //外部存储
            File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+File.separator+"FileStorage",mFinalName);
            fileInputStream = new FileInputStream(file);
            byte[] buff = new  byte[1024];
            //实现字符串拼接
            StringBuilder sb = new StringBuilder("");
            int len = 0;
            while ((len = fileInputStream.read(buff)) > 0){
                sb.append(new String(buff,0,len));
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream!=null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}

布局文件和上面的一样:
此外要在AndroidManifest.xml里添加两行代码,用来获取存储权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

这里在真机上运行出现如需下错误:

暂时没有解决。

原文地址:https://www.cnblogs.com/yangdd/p/13376252.html