文件存儲是 Android 中最基本的一種數據存儲方式,所有數據都是直接保存到文件中的,所以它適用于存儲一些簡單的文本數據或二進制數據。
1 存儲數據
Context 類有一個 openFileOutput () 方法,用于將數據存儲到指定文件中。
openFileOutput () 方法參數:
參數 | 描述 |
---|---|
文件名 | 文件名不包含路徑,文件默認存儲在 /data/data/<packagename>/files/ 路徑下。 |
操作模式 | MODE_PRIVATE(默認):存在同名文件時,就直接覆蓋原文件內容;MODE_APPEND:存在同名文件時,就在原文件的末尾追加內容;MODE_WORLD_READABLE 與 MODE_WORLD_WRITEABLE 已廢棄(Android 4.2+) |
我們新建一個項目,然后修改布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="net.deniro.android.filepersistence.MainActivity">
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="請輸入" />
</RelativeLayout>
這里只是在布局中加入了一個 EditText 控件,用于輸入文本內容。我們的目的是在文本輸入框中隨意輸入內容,然后按下 Back 鍵,將輸入的內容保存到文件中,即持久化。
主活動代碼:
public class MainActivity extends AppCompatActivity {
private EditText editText;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.edit_text);
}
@Override
protected void onDestroy() {
super.onDestroy();
save(editText.getText().toString());
}
/**
* 保存到文件
*
* @param value
*/
private void save(String value) {
BufferedWriter writer = null;
try {
FileOutputStream out = openFileOutput("myData", Context.MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(value);
} catch (FileNotFoundException e) {
Log.e(TAG, "save: 找不到文件", e);
} catch (IOException e) {
Log.e(TAG, "save:IO 異常", e);
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
Log.e(TAG, "save: 無法關閉 BufferedWriter", e);
}
}
}
}
我們在 onCreate() 方法中獲取 editText 實例,然后在重寫的 onDestroy() 方法中,把 editText 實例中的內容保存到文件中,進行持久化操作。
運行程序:
然后按下 Back 鍵關閉程序,這樣我們所輸入的內容就已經保存在文件中咯。這可以通過 Android Device Monitor 看到結果(Android Studio → Tools → Android)
如果是 debug 模式,會彈出以下窗口,我們點擊 Yes:
這時就會彈出 Android Device Monitor,我們選擇 File Explorer:
然后在 data/data/項目包名/files/ 下找到我們剛才生成的 myData 文件。如果無法打開 data 文件夾,請點擊 在 Android Device Monitor 的 File Explorer 中,無法打開某些文件夾的解決方法
然后點擊右上的 Pull a file from the device:
如果系統報 Failed to pull selection: open failed: Permission denied
,請點擊 Android Device Monitor 報 open failed: Permission denied 問題的解決方法
打開這個數據文件,里面的內容就是我們剛才在 EditText 中輸入的內容咯O(∩_∩)O哈哈~
2 獲取數據
Context 類中還提供了一個 openFileInput() 方法,用于從文件中讀取數據。它只接收一個參數,即要讀取的文件名,然后系統會自動從 data/data/<包名>/files/
中加載這個文件,并返回 FileInputStream 對象。
我們修改主活動類,在 onCreate() 方法中加入 “獲取文件數據” 的方法 :
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editText = (EditText) findViewById(R.id.edit_text);
String text = get();
if (!TextUtils.isEmpty(text)) {
editText.setText(text);
editText.setSelection(text.length());
Toast.makeText(this, "讀取成功O(∩_∩)O哈哈~", Toast.LENGTH_LONG).show();
}
}
/**
* 從文件中獲取數據
*
* @return
*/
private String get() {
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
FileInputStream in = openFileInput("myData");
reader = new BufferedReader(new InputStreamReader(in));
String temp;
while ((temp = reader.readLine()) != null) {
content.append(temp);
}
} catch (FileNotFoundException e) {
Log.e(TAG, "get: FileNotFoundException", e);
} catch (IOException e) {
Log.e(TAG, "get: IOException", e);
}
return content.toString();
}
這里使用了 TextUtils.isEmpty() 方法,它可以檢測 null 與空字符串,所以使用起來很方便,下面是它的源碼:
public static boolean isEmpty(@Nullable CharSequence str) {
if (str == null || str.length() == 0)
return true;
else
return false;
}
重新運行程序: