Android数据存储(一)

1. Android 文件系统简介

Android的文件分为内部存储(internalstorage)和外部存储(external stor-age)两大类型。

1.1 内部存储

内部存储为手机等设备的内存空间,它挂载在Android系统的system/、data/等目录下在SDK版本变迁中,内部存储的功能定位和挂载路径没有发生变化。开发者可以使用模扣器+adb shell进人文件系统,或者使用 Android Studio 的 Device File Explorer 插件查看内部空间。

system/目录一般用于存储 Android 的系统数据,开发者无法进行读写。

data/目录一般存放缓存数据、用户应用程序数据等,具体的路径为data/data/

内部存储的应用程序数据在应用卸载时被全部删除。

1.2 外部存储

外部存储变化较大,Android4.4以前,外部存储仅仅指SD卡、TF卡之类的外挂移动存储设备;Android4.4及其以后,外部存储包括内置的外部存储和外挂的SD卡等存储设备当然,有些机器没有提供外接SD卡的功能,就只有内置的外部存储空间。外部存储一般存储应用程序的业务数据,如视频文件、音频文件、表格、日志、下载文件等。在Android系统中,外部存储一般挂在storage/emulated/0或者storage/sdcard/0目录下。

2. 内部存储的应用

2.1 内存文件的数据存取

内存文件的数据存取有两种方式,一种是写入在内存中,拥有较快的速度,另一种是写入到硬盘中,速度较慢,有Context的openFilelnput()方法可用来获取文件输人流,Context的openFileOutput()方法可用来获取文件输出流。

属性 描述
ContexL.MODE_PRIVATE=0 默认的私有模式,只有本应用才可以访问。
ContexL.MODE_APPEND=32768 如文件存在,则追加内容,如不存在,则新建文件。
Context.MODE_WORLDREADABLE=1 当前文件可被其他应用读取。
eContext.MODE_WORLD_WRITEABLE=2 当前文件可被其他应用写入。

2.2 SharedPerferences简介

SharedPerferences组件实现的数据存储是内存文件存储的,当我们需要存储键值对数据时,使用这个组件是非常不错的选择,它它屏蔽了文件读写的细节,为开发者提供简单易用的访问接口。SharedPreferences适合于数据量小的参数配置、简单信息存储等场合,数据以XML文件形式存储在/data/data/<应用包名>/shared_refs日录下。

方法 描述
public abstract SharedPreferences. Editor edit( ) 获取数据编辑器
public abstract Map < String,?> getAll( ) 取出全部键值对
public abstract boolean getBoolean ( String key, boolan default ) 获取 boolean 型数据,并给出默认值
public abstract int getInt( String key, int default ) 获取int型数据,并给出默认值
public abstract long getLong( String key, long default ) 获取 long型数据,并给出默认值
public abstract String getString( String key, String default) 获取 String型数据,并给出默认值
public abstract contains ( String key ) 判断某个 key 是否存在

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
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
<?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:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CCC6C6"
android:orientation="vertical"
tools:context=".easy_Activity">

<TextView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#AB9F9F"
android:gravity="center"
android:text="内存读取"

android:textSize="23dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
android:layout_margin="20dp"
android:layout_weight="8">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="留言标题:"
android:textSize="30dp" />

<EditText
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:hint="输入标题"
android:layout_marginTop="10dp"
android:textSize="30dp"
android:minHeight="49dp"
/>

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="留言内容:"
android:textSize="30dp" />

<EditText
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
android:hint="内容"
android:layout_marginTop="10dp"
android:textSize="30dp"
android:minLines="7"
android:ems="10"
android:inputType="textMultiLine"
android:scrollbars="vertical"
android:layout_gravity="left|right"
/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:orientation="horizontal">

<Button
android:id="@+id/save"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="保存"
android:layout_width="wrap_content"/>
<Button
android:id="@+id/reset"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="清空"
android:layout_width="wrap_content"/>
<Button
android:id="@+id/loding"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="加载"
android:layout_width="wrap_content"/>
</LinearLayout>
</LinearLayout>
image-20241022190617623

3.1 Stream流用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 写入
String s = title.getText().toString();
String contents = content.getText().toString();
OutputStream os = openFileOutput(fileName, Context.MODE_PRIVATE);
os.write(s.getBytes());
os.write("\n".getBytes());
os.write(contents.getBytes());
os.close();

// 读取
InputStream is = openFileInput(fileName);
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String firstLine = br.readLine();
String secondLine = br.readLine();
title.setText(firstLine);
content.setText(secondLine);
br.close();

3.2 SharedPreferences用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 //写入
SharedPreferences sharedPreferences = getSharedPreferences("sharedCode",MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("title",s);
editor.putString("content",contents);
// 写入文件
editor.commit();
// 写入内存
// editor.apply();


//读取
SharedPreferences sharedPreferences = getSharedPreferences("sharedCode",MODE_PRIVATE);
String firstLine = sharedPreferences.getString("title","");
String secondLine = sharedPreferences.getString("content","");
title.setText(firstLine);
content.setText(secondLine);

以上就可以实现对数据进行存储了,在第二种方式中,关闭应用重新启动后依旧可以读取到其中的数据。

4. 查看存储文件

1729595807264.png

按照上述打开文件管理页面,进入其中的/data/data/包名/shared prefs/java中定义的文件名.xml

1
2
3
4
5
6
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="title">biaoti</string>
<string name="content">neirong</string>
</map>

可以看见我们的数据以键值对的形式存储在了其中。