我们有时候可以将数据直接以文件的形式保存在设备中,例如:文本文件,图片文件等等

使用File进行存储操作主要使用到以下的

①:public abstract FileInputStream openFileInput (String name)

这个主要是打开文件,返回FileInputStream

②:public abstract FileOutputStream openFileOutput (String name, int mode)

这个主要是写入文件,如果该文件不存在,直接进行创建,返回FileOutputStream

Mode(主要有以下的四种的模式)

MODE_APPEND  //在尾部追加
MODE_PRIVATE //私有
MODE_WORLD_READABLE //可读
MODE_WORLD_WRITEABLE //可写

③:FileInputStream(获取文件输入流)与FileOutputStream (获取文件输出流)这两类在JavaIO 操作中很常见

接下来进行操作 保存成功之后讲文件保存在当前应该程序的包名下的files/(可以改变存储的其他路径)

下面看一个实例:

一、效果图


开发怎么获取android13存储权限 安卓开发文件存储_开发怎么获取android13存储权限

         

开发怎么获取android13存储权限 安卓开发文件存储_android_02

二、敲代码

布局代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <EditText
        android:id="@+id/et"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:background="@drawable/border"
        android:hint="请输入你想保存的内容:" />

    <Button
        android:id="@+id/btn_save"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:text="保存数据"
        android:textSize="20dp" />

    <Button
        android:id="@+id/btn_get"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:layout_marginTop="100dp"
        android:text="读取数据"
        android:textSize="20dp" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:textColor="#000"
        android:layout_height="100dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/border"
        android:textSize="15dp" />
</LinearLayout>

布局文件设置的很简单,就设计了一个编辑框,用于输入数据,一个按钮用来保存输入的数据;然后一个文本框用来输出数据,一个按钮用来取出数据。

MainActivity中的代码:

public class MainActivity extends AppCompatActivity {

    private EditText et;
    private Button btn_save, btn_get;
    private TextView tv;

    private static final String FILENAME = "text.txt";

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

        initView();
    }

    private void initView() {
        et = (EditText) findViewById(R.id.et);
        tv = (TextView) findViewById(R.id.tv);

        btn_save = (Button) findViewById(R.id.btn_save);
        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String inputText = et.getText().toString();
                if (inputText == null) {
                    Toast.makeText(MainActivity.this, "数据为空", Toast.LENGTH_SHORT).show();
                } else {
                    write(inputText);
                    Toast.makeText(MainActivity.this, "保存数据成功!", Toast.LENGTH_SHORT).show();
                }
            }
        });


        btn_get = (Button) findViewById(R.id.btn_get);
        btn_get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.setText(read());
                Toast.makeText(MainActivity.this, "数据读取成功!", Toast.LENGTH_SHORT).show();
            }
        });
    }

    // 读文件方法
    private String read() {
        try {
            FileInputStream inputStream = openFileInput(FILENAME);
            byte[] b = new byte[inputStream.available()];
            inputStream.read(b);
            return new String(b);
        } catch (Exception e) {
        }
        return null;
    }

    // 写文件
    private void write(String content) {
        try {
            FileOutputStream fos = openFileOutput(FILENAME, MODE_APPEND);
            fos.write(content.getBytes());
            fos.close();
        } catch (Exception e) {
        }
    }

}

这里主要就是使用了FileInputStream(获取文件输出流)和FileOutputStream(获取文件输入流)来对文件进行了操作。使用这两个对象来对文件进行操作,看起来很简单,实际上是有很大缺陷的,因为它读取或者写入文件的方式是以一个字节为单位的,每次读取或者写入一个 字节就会执行一次IO,我们知道IO的操作是很费时的,这就会导致程序的 效率低下。为了解决这个问题,我们推荐使用BufferedReader类和BufferedWriter类,它们可以一次读取大量的数据,这样就大大减少了IO次数,效率大大提升。


BufferedReader和BufferedWriter方法实现文件读写的代码写到了Main2Activity中:

public class Main2Activity extends AppCompatActivity{
    private EditText et;
    private Button btn_save, btn_get;
    private TextView tv;

    private static final String FILENAME = "text.txt";

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

    private void initView() {
        et = (EditText) findViewById(R.id.et);
        tv = (TextView) findViewById(R.id.tv);

        btn_save = (Button) findViewById(R.id.btn_save);
        btn_save.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final String inputText = et.getText().toString();
                //TextUtils.isEmpty()方法可以一次性进行两种空值的判断。当传入的字符串等于null或者等于空字符串的时候,这个方法都会返回true.
                //if (!TextUtils.isEmpty(inputText)) {
                if (inputText == null) {
                    Toast.makeText(Main2Activity.this, "数据为空", Toast.LENGTH_SHORT).show();
                } else {
                    //若没有来得及点下保存按钮,就退出了APP,那么若还希望能够保存数据,则save()函数应该放到onDestroy()中。
                    save(inputText);
                    Toast.makeText(Main2Activity.this, "保存数据成功!", Toast.LENGTH_SHORT).show();
                }
            }
        });


        btn_get = (Button) findViewById(R.id.btn_get);
        btn_get.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                tv.setText(load());
                Toast.makeText(Main2Activity.this, "数据读取成功!", Toast.LENGTH_SHORT).show();
            }
        });
    }


    private void save(String inputText) {

        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            //openFileOutput()方法可以用于将数据保存到指定的文件中。
            //这个方法接受两个参数,第一个参数是文件名,在文件创建的时候使用的就是这个名称
            //注意,这里指定的文件名不能包含路径,因为所有的文件都是默认存储到/data/data/<package name>/files/目录下的
            //第二个参数是文件的操作模式,有两种模式可选:
            // MODE_PRIVATE是默认的操作模式,表示当指定同样文件名的时候,所写入的内容将会覆盖原文件中的内容。
            //MODE_APPEND则表示如果该文件已存在,就往文件里面追加内容。
            out = openFileOutput(FILENAME, Context.MODE_PRIVATE);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(inputText);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (writer != null) {
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private String load() {
        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();
        try {
            in = openFileInput(FILENAME);

            reader = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


}