啥是内部存储
内部存储位于系统中很特殊的一个位置,如果将文件存储在内部存储中,那么文件只能默认被你的应用访问到,并且同一个应用创建的所有文件都在相同的目录下。创建于内部存储的文件与应用相关联,应用卸载后文件也被删除。
内部存储所有内容都在安卓文件系统下的 data,其中 data 又有三个子目录:
data
|- app
|- data
|- local
- app 存放所有安装的app的apk文件
- data 文件夹里面都是一些包名,这些包名和 build.gradle 中 applicationId 是一致的,也就是说你的应用的一些数据就在在这里
- local 存放临时的缓存文件
我们重点关注 data文件。打开 Audio Studio --> View --> Tool Windows --> Device File Explorer,找到 data/data 文件夹,可以查看里头确实都是一些包名。
在内部存储中读写文件
写文件
在内部存储写文件时,首先要获得文件正确的路径,可以用下面两个方法:
getFilesDir()
: 返回存放应用文件的路径
getCacheDir()
: 返回存放应用临时缓存的路径
结合文件名和上面的两种方法,得到正确的文件路径,然后打开文件进行写入操作。例如
String filename = "test.txt";
File file = new File(getFilesDir(), filename);
try {
FileOutputStream outputStream = new FileOutputStream(file);
} catch (Exception e) {
e.printStackTrace();
}
或者,用 openFileOutput()
来直接获得一个 FileOutputStream
,例如:
try {
FileOutputStream outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
} catch (Exception e) {
e.printStackTrace();
}
注意,openFileOutput
需要一个文件模式参数。MODE_PRIVATE
表示这个文件是这个应用私用的文件,外部不可访问。其他的文件模式有 MODE_WORLD_READABLE
和 MODE_WORLD_WRITEABLE
已经在安卓7.0后被弃用了。如果你的app要分享私有文件,那么可以使用 FileProvider
,这个我们下次再聊。
读文件
读文件的操作与写文件类似,不再累述,直接上代码:
String filename = "test.txt";
File file = new File(getFilesDir(), filename);
try {
FileInputStream inputStream = new FileInputStream(file);
} catch (Exception e) {
e.printStackTrace();
}
或者用 openFileInput
,注意这里不需要文件模式参数
try {
FileInputStream inputStream = openFileInput(filename);
} catch (Exception e) {
e.printStackTrace();
}
小例子
ok,我们已经掌握了在内部存储读写文件的所有内容了,现在来做一个小作业,用上我们学到的知识。
需求是这样,做一个下图样式的app,在文本框里输入文字,点击Save
将文件保存至文件,点击Read
将保存的文件读入并显示在文本框里。
具体如何做就不一一细说了,直接上代码
MainActivity.java
package com.bytedance.writeandreadoninternalstorage;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final String filename = "test.txt";
private Button saveButton;
private Button readButton;
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
saveButton = findViewById(R.id.save);
readButton = findViewById(R.id.read);
editText = findViewById(R.id.editText);
}
public void onSaveClicked(View view) {
try {
FileOutputStream outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
String text = editText.getText().toString();
outputStream.write(text.getBytes());
Toast.makeText(this, "Save success!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
public void onReadClicked(View view) {
try {
FileInputStream inputStream = openFileInput(filename);
byte[] bytes = new byte[1024];
int hasRead = inputStream.read(bytes);
editText.setText(new String(bytes, 0, hasRead));
Toast.makeText(this, "Read success!", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:hint="Enter..."
android:maxLines="20"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:text="Save"
android:onClick="onSaveClicked"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@+id/read"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/editText" />
<Button
android:id="@+id/read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Read"
android:onClick="onReadClicked"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@id/save"
app:layout_constraintTop_toBottomOf="@id/editText" />
</androidx.constraintlayout.widget.ConstraintLayout>