数据存储一:临时存储和文件存储

Author Avatar
Euan 11月 01, 2019
  • 在其它设备中阅读本文章

数据存储一:临时存储和文件存储

实验目的

1.了解Android数据存储的基本方法
2.掌握SharedPreferences、内部文件存储、外部存储的技术
实验内容:
(1)尝试使用SharedPreferences在程序关闭时保存用户输入的信息,并在程序重新启动时自动恢复这些信息。(2)以INI文件的形式,将数据保存在内部或外部存储器上,实现相同的功能
实验原理:

一、SharedPreferences

1、SharedPreferences 简介

SharedPreferences是一种轻量级的永久性的数据保存方式。通过SharedPreferences开发人员可以将NVP(Name/Value Pair,名称/值对)保存在Android内部存储器的文件系统中,而不需关心文件系统的操作过程。
一般用于:保存应用程序的配置信息和个性化内容。
也可用于:不同应用程序间的数据共享。

2、SharedPreferences支持三种访问模式

 私有(MODE_PRIVATE):仅创建SharedPreferences的程序有权限对其进行读取或写入
 全局读(MODE_WORLD_READABLE):不仅创建程序可以对其进行读取或写入,其它应用程序也具有读取操作的权限,但没有写入操作的权限
 全局写(MODE_WORLD_WRITEABLE):所有程序都可以对其进行写入操作,但没有读取操作的权限

3、使用过程

1)定义常量

1
2
3
4
/*定义访问模式*/
public static int MODE = MODE_PRIVATE;
/*定义一个SharedPreferences名。之后将以这个名字保存在Android文件系统中*/
public static final String PREFERENCE_NAME = "SaveSetting";

2)往SharedPreferences中写数据

1
2
3
4
5
6
7
8
              /*获取SharedPreferences实例  */
SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCE_NAME, MODE);
/*通过SharedPreferences.Editor类向SharedPreferences中写键值,调用commit()保存修改内容*/
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("Name", "Tom");
editor.putInt("Age", 20);
editor.putFloat("Height", 1.81f);
editor.commit();

3)从SharedPreferences中读数据

1
2
3
4
5
6
/*获取SharedPreferences实例。如果不存在将新建一个  */
SharedPreferences sharedPreferences = getSharedPreferences(PREFERENCE_NAME, MODE);
/*读取SharedPreferences中保存的键值:如果文件或键值不在,则用缺省值 */
String name = sharedPreferences.getString("Name","Default Name");
int age = sharedPreferences.getInt("Age", 20);
float height = sharedPreferences.getFloat("Height",1.81f);

4、查看SharedPreferences文件

通过eclipse 的菜单window->show view-> other->android->file explorer可以查看模拟器上的文件。
SharedPreferences产生的文件就保存在/data/data//shared_prefs目录下
选中文件,点击右上角:pull a file from a device可另存该文件。

二、内部存储:直接使用文件保存数据

1、简介

Android系统允许应用程序创建仅能够自身访问的私有文件,文件保存在设备的内部存储器上,即Android系统下的/data/data//files目录中
可通过文件访问权限的控制保证文件的私密性
四种文件操作模式

模式 说明
MODE_PRIVATE 私有模式,文件仅能被创建文件的程序访问,或具有相同UID的程序访问。
MODE_APPEND 追加模式,如果文件已经存在,则在文件的结尾处添加新数据。
MODE_WORLD_READABLE 全局读模式,允许任何程序读取私有文件。
MODE_WORLD_WRITEABLE 全局写模式,允许任何程序写入私有文件。

因为流文件操作可能会遇到各种问题而最终导致操作失败,在实际操作过程中会遇到错误提示,因此代码应该使用try/catch捕获可能产生的异常

2、文件输出基本过程:将字符串写入文件,文件作为输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FileOutputStream fos = null;
try {
fos = openFileOutput(fileName,Context.MODE_PRIVATE);
fos.write(text.getBytes()); //String类型变量text:保存了需要写入文件的内容
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally{
if (fos != null){
try {
fos.flush();
fos.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}

说明:
1)行3中fileName不可以包含描述路径的斜杠
2)调用close()之前务必调用flush()将缓冲中的所有数据写入文件
3)openFileOutput打开应用的私有文件,如果文件不存在则创建。
4)FileOutputStream是写到文件的字节流

3、文件输入基本过程:读取文件内容到字符串,文件作为输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FileInputStream fis = null;
try {
fis = openFileInput(fileName);
if (fis.available() == 0){
return;
}
byte[] readBytes = new byte[fis.available()];
while(fis.read(readBytes) != -1);
String text = new String(readBytes); //String类型变量text:保存从文件中读取的内容
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
finally{
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}

说明:
1)FileInputStream 的方法available() 返回估计可读的字节数.
2)public int read (byte[] buffer, int byteOffset, int byteCount)
最多从字节流中读byteCount个字节,并存储在字节数组缓冲buffer中,存放时放在byteOffset指定的在buffer的位置。返回实际读的字节数,或者如果读到流的末尾了就返回-1.
运行程序后,在文件浏览器中可查看:

VGmiLj.png

导出输出的流文件,可查看内容。
另外,注意只有当应用在模拟器上运行起来后,才能使用File Explore看到保存的文件。

三、外部存储

1、外部存储应用场合

Micro SD卡适用于保存大尺寸的文件或者是一些无需设置访问权限的文件
如果用户希望保存录制的视频文件和音频文件,因为Android设备的内部存储空间有限,所以使用Micro SD卡则是非常适合的选择
但如果需要设置文件的访问权限,则不能够使用Micro SD卡,因为Micro SD卡使用FAT(File Allocation Table)文件系统,不支持访问模式和权限控制

2、使用外部存储的前提条件

正确加载SD卡后,SD卡中的目录和文件被映射到/mnt/sdcard目录下
因为用户可以加载或卸载SD卡,所以在编程访问SD卡前首先需要检测/mnt/sdcard目录是否可用
如果不可用,说明设备中的SD卡已经被卸载。如果可用,则直接通过使用标准的java.io.File类进行访问

3、编码时与内部存储的区别

1.与内部存储的核心代码比较相似,不同之处在于代码中添加了/mnt/sdcard目录存在性检查,并使用“绝对目录+文件名”的形式表示新建立的文件,并在写入文件前对文件的存在性和可写入性进行检查

4、程序运行时,若发生“SD 卡不存在或不可写”的错误,

1)检查是否在manifest.xml文件中增加使用许可;
1
2
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"> </uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"> </uses-permission>
2)检查模拟器中对SD卡的设置是否正确,比如,需要设置SD卡的存储容量。

实验步骤:

要求:

1)可以参考教材上的例子,但一定不要直接拷贝;
2)将实验代码和运行效果截图放在实验报告中提交。

1.使用SharedPreferences保存用户输入的信息

1)建立一个项目“SharedPreferencesDemo”
2)自行设计该应用的用户界面(注意:在界面里要有接受用户输入的控件,比如,可以设计一个“设置”Activity,用户打开这个Activity时,从配置文件里读取用户设置,当用户修改设置后将更改后的设置保存到配置文件中),参考界面如下:

VGmkes.png

3)为用户界面添加事件处理函数,在适当的事件里添加读取和保存配置文件的代码。

2.以INI文件的形式,将数据保存在内部或外部存储器上,实现相同的功能

1)建立一个项目“FileStoreDemo”
2)用户界面可以与前面相同
3)可使用内部存储或外部存储保存配置到ini文件(字段格式自定),可参考”实验原理”部分内容实现。

程序一(使用SharedPreferences保存用户输入的信息)源代码

ActivityA.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.self.user.sharedpreferencesdemo;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
* Package: com.self.user.sharedpreferencesdemo
* Created by zyh
* on 2019/6/2
*/
public class ActivityA extends AppCompatActivity {

public static SharedPreferences preferences;
public static final String PREF_NAME = "MyApp_pref";

/*Views*/
private EditText et_username = null;
private EditText et_password = null;
private Button loginBtn = null;

/*String values*/
String enteredUsername = "", enteredPassword = "";

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

// initialize SharedPreference
preferences = getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);

// initialize views
et_username = findViewById(R.id.et_userName);
et_password = findViewById(R.id.et_password);
loginBtn = findViewById(R.id.login_button);

if(existingUser()) {
startActivity(new Intent(ActivityA.this, ActivityB.class));
finish();
}

loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isValid()) {
AppSharedPreferences.setPreference(getApplicationContext(), AppSharedPreferences.Pref_UserName, enteredUsername);
AppSharedPreferences.setPreference(getApplicationContext(), AppSharedPreferences.Pref_Password, enteredPassword);
startActivity(new Intent(ActivityA.this, ActivityB.class));
finish();
}
}
});

}

private boolean isValid() {
enteredUsername = et_username.getText().toString();
enteredPassword = et_password.getText().toString();
if(TextUtils.isEmpty(enteredUsername)) {
et_username.setError("Please enter a username");
et_username.requestFocus();
return false;
} else if(TextUtils.isEmpty(enteredPassword)) {
et_password.setError("Please enter a password");
et_password.requestFocus();
return false;
}
return true;
}

private boolean existingUser() {
return !TextUtils.isEmpty(AppSharedPreferences.getPreferences(getApplicationContext(), AppSharedPreferences.Pref_UserName));
}

}

ActivityB.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.self.user.sharedpreferencesdemo;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
/**
* Package: com.self.user.sharedpreferencesdemo
* Created by zyh
* on 2019/6/2
*/
public class ActivityA extends AppCompatActivity {

public static SharedPreferences preferences;
public static final String PREF_NAME = "MyApp_pref";

/*Views*/
private EditText et_username = null;
private EditText et_password = null;
private Button loginBtn = null;

/*String values*/
String enteredUsername = "", enteredPassword = "";

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

// initialize SharedPreference
preferences = getApplicationContext().getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE);

// initialize views
et_username = findViewById(R.id.et_userName);
et_password = findViewById(R.id.et_password);
loginBtn = findViewById(R.id.login_button);

if(existingUser()) {
startActivity(new Intent(ActivityA.this, ActivityB.class));
finish();
}

loginBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isValid()) {
AppSharedPreferences.setPreference(getApplicationContext(), AppSharedPreferences.Pref_UserName, enteredUsername);
AppSharedPreferences.setPreference(getApplicationContext(), AppSharedPreferences.Pref_Password, enteredPassword);
startActivity(new Intent(ActivityA.this, ActivityB.class));
finish();
}
}
});

}

private boolean isValid() {
enteredUsername = et_username.getText().toString();
enteredPassword = et_password.getText().toString();
if(TextUtils.isEmpty(enteredUsername)) {
et_username.setError("Please enter a username");
et_username.requestFocus();
return false;
} else if(TextUtils.isEmpty(enteredPassword)) {
et_password.setError("Please enter a password");
et_password.requestFocus();
return false;
}
return true;
}

private boolean existingUser() {
return !TextUtils.isEmpty(AppSharedPreferences.getPreferences(getApplicationContext(), AppSharedPreferences.Pref_UserName));
}

}

AppSharedPreferences.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.self.user.sharedpreferencesdemo;

import android.content.Context;
import android.content.SharedPreferences;
/**
* Package: com.self.user.sharedpreferencesdemo
* Created by zyh
* on 2019/6/2
*/
public class AppSharedPreferences {

public static final String Pref_UserName = "UserName";
public static final String Pref_Password = "Password";

/******** set shared preferences ***************/
public static void setPreference(Context context, String key, String value) {
// save the data
SharedPreferences.Editor editor = ActivityA.preferences.edit();
editor.putString(key, value);
editor.apply();
}

/**
* ******** get shared preferences ****************
*/
public static String getPreferences(Context context, String key) {
return ActivityA.preferences.getString(key, "");
}

/**
* ******** set boolean preferences ****************
*/
public static void setBooleanPreferences(Context context, String key, boolean value) {
SharedPreferences.Editor mSharedPrefsEditor = ActivityA.preferences.edit();
mSharedPrefsEditor.putBoolean(key, value);
mSharedPrefsEditor.apply();
}

/**
* ******** get boolean preferences ****************
*/
public static boolean getBooleanPreferences(Context context, String key) {
return ActivityA.preferences.getBoolean(key, false);
}

/**
* *******clear all data from shared preference*********
*/
public static void clearPreference(Context context) {
SharedPreferences.Editor editor = ActivityA.preferences.edit();
editor.clear();
editor.apply();
}

/**
* *******remove perticular key value*********
*/
public static boolean removeKeyValue(Context context, String key) {
SharedPreferences.Editor editor = ActivityA.preferences.edit();
editor.remove(key);
editor.apply();
return true;
}

}

activity_a.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="20dp"
tools:context=".ActivityA">

<EditText
android:id="@+id/et_userName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:hint="Username"
android:imeOptions="actionNext"
android:inputType="text"
android:maxLength="15"
android:maxLines="1"
android:text=""
android:textColor="@android:color/black"
android:textSize="16sp"
tools:ignore="HardcodedText" />

<EditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="Password"
android:imeOptions="actionDone"
android:inputType="textPassword"
android:maxLength="15"
android:maxLines="1"
android:text=""
android:textColor="@android:color/black"
android:textSize="16sp"
tools:ignore="HardcodedText" />

<Button
android:id="@+id/login_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:background="@color/colorPrimary"
android:text="Login"
android:textColor="@android:color/white"
android:textSize="20sp"
tools:ignore="HardcodedText" />

</LinearLayout>

activity_b.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="20dp"
tools:context=".ActivityB">

<TextView
android:id="@+id/tv_greeting"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center_horizontal"
android:text="Welcome"
android:textColor="@android:color/black"
android:textSize="25sp"
tools:ignore="HardcodedText" />

<Button
android:id="@+id/logout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="50dp"
android:background="@color/colorPrimary"
android:text="Logout"
android:textColor="@android:color/white"
android:textSize="20sp"
tools:ignore="HardcodedText" />

</LinearLayout>

程序一(使用SharedPreferences保存用户输入的信息)功能简介

密码检查模块(与实验五相同)不再说明
VGDE7R.png
VGDZA1.png

案例一:
登陆前
VGDetx.png

登陆后,保留账号信息并且显示欢迎界面
VGDAB9.png

案例二:
登陆前
VGDTER.png

登陆后,保留账号信息并且显示欢迎界面
VGD7U1.png

文件内容
VG57O1.png

程序二(以INI文件的形式/内部存储)源代码

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package com.codeteenageer.filestoredemo;
/**
* Package: com.codeteenageer.filestoredemo
* Created by zyh
* on 2019/5/27
*/
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class MainActivity extends AppCompatActivity {
private EditText et;
private TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = (EditText) findViewById(R.id.et);
tv = (TextView) findViewById(R.id.tv);
}

public void save(View view) {
save(et.getText().toString());
}

public void get(View view) {
tv.setText(getData());
}

private void save(String data) {
FileOutputStream out = null;
BufferedWriter writer = null;
try {
out = openFileOutput("data.ini", MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}

}
}

private String getData() {
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try {
in = openFileInput("data.ini");
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 content.toString();
}
}

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?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="com.codeteenageer.filestoredemo.MainActivity">

<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="save"
android:text="保存" />

<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="数据显示" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="get"
android:text="获取" />

</LinearLayout>

程序二(以INI文件的形式/内部存储)功能简介

点击保存,后自动保存到ini文件
获取即显示数字
VG47a8.png

ini文件
VG4IqP.png

程序三(以INI文件的形式/外部存储)源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package org.crazyit.io;
/**
* Package: com.codeteenageer.filestoredemo
* Created by zyh
* on 2019/5/27
*/

import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;


public class MainActivity extends Activity {
final String FILE_NAME = "/zyh.ini";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取两个按钮
Button read = (Button) findViewById(R.id.read);
Button write = (Button) findViewById(R.id.write);
// 获取两个文本框
final EditText edit1 = (EditText) findViewById(R.id.edit1);
final EditText edit2 = (EditText) findViewById(R.id.edit2);
// 为write按钮绑定事件监听器
write.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View source) {
// 将edit1中的内容写入文件中
write(edit1.getText().toString());
edit1.setText("");
}
});
read.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// 读取指定文件中的内容,并显示出来
edit2.setText(read());
}
});
}

private String read() {
try {
// 如果手机插入了SD卡,而且应用程序具有访问SD的权限
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// 获取SD卡对应的存储目录
File sdCardDir = Environment.getExternalStorageDirectory();
System.out.println("----------------" + sdCardDir);
// 获取指定文件对应的输入流
FileInputStream fis = new FileInputStream(
sdCardDir.getCanonicalPath() + FILE_NAME);
// 将指定输入流包装成BufferedReader
BufferedReader br = new BufferedReader(new
InputStreamReader(fis));
StringBuilder sb = new StringBuilder("");
String line = null;
// 循环读取文件内容
while ((line = br.readLine()) != null) {
sb.append(line);
}
// 关闭资源
br.close();
return sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

private void write(String content) {
try {
// 如果手机插入了SD卡,而且应用程序具有访问SD的权限
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
// 获取SD卡的目录
File sdCardDir = Environment.getExternalStorageDirectory();
File targetFile = new File(sdCardDir
.getCanonicalPath() + FILE_NAME);
// 以指定文件创建 RandomAccessFile对象
RandomAccessFile raf = new RandomAccessFile(
targetFile, "rw");
// 将文件记录指针移动到最后
raf.seek(targetFile.length());
// 输出文件内容
raf.write(content.getBytes());
// 关闭RandomAccessFile
raf.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?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">

<EditText
android:id="@+id/edit1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lines="4" />

<Button
android:id="@+id/write"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/write" />

<EditText
android:id="@+id/edit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:cursorVisible="false"
android:lines="4" />

<Button
android:id="@+id/read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/read" />
</LinearLayout>

程序三(以INI文件的形式/外部存储)功能简介

输入文本,保存,读取,设置为wr,往文件后面继续写
VG5TyR.png

文件位置
VG5bex.png

本文使用 CC BY-NC-SA 3.0 中国大陆 协议许可
具体请参见 知识共享协议

本文链接:https://zyhang8.github.io/2019/11/01/android-exp6/