Android数据存储

五种存储方式

  • 文件存储:通过io流的形式,类似java的io流文件存储
  • SharedPreferences:Android提供的一些简单配置信息的机制
  • SQLite数据库存储:Android自带的轻量级数据库,支持sql
  • ContentProvider:Android四大组件,可以把数据共享给其他应用
  • 网络存储:通过网络空间

文件存储

分为内部存储和外部存储

默认路径 性质
内部存储 /data/data//files/目录 在程序内,程序卸载,存储文件就会删除
外部存储 通常mnt/sdcard目录下 外部设备上比如sd卡,程序卸载,存储文件不会删除
内部存储实现

读操作(即读取)核心类

  • openFileInput(String name)读取文件,打开指定输出流
  • name:打开文件名,不包含路径分隔符
  • 返回类型:FileInputStream

关键代码

1
2
3
4
5
6
7
FileInputStream in = openFileInput("data.txt");
ButteredReader reader = new ButteredReader(new InputStreamReader(in));
StringBuilder builder = new StringBuilder();
String line= "";
while((line = reader.readline()) != null){
builder.append()
}

写操作(即存储)核心类

  • openFileOutputStream(String name,int mode)保存文件,打开指定输出流
  • name:打开文件名,不包含路径分隔符
  • mode:操作模式
  • 返回类型:FileOutputStream

关键代码

1
2
3
4
String data = " data";
FileOutputStream out = openFileOutput("data.txt",Context.MODE_PRIVATE);
ButteredWriter writer = new ButteredWriter(new OutputSreamWriter(out));
writer.write(data);

文件操作模式

模式 操作(mode取值)
MODE_PRIVATE 默认操作模式,代表私有数据,只能应用本身访问,写入内容会被覆盖,就是说永远保存的是最后内容
MODE_APPEND 检查文件是否存在,不存在就创建文件,否则追加内容
外部存储实现
  • 外部设备需要确认是否可用,调用getExternalStorageState()
  • 外部设备可用且有读写权限才能进行操作做
文件存储的例子

样式文件

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
<?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=".MainActivity">

<LinearLayout
android:layout_width="match_parent"
android:layout_height="145dp"
android:layout_weight="1"
android:orientation="horizontal">

<EditText
android:id="@+id/et"
android:layout_width="134dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="输入内部存储内容"
android:inputType="textPersonName" />

<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="save"
android:text="保存" />

<Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="read"
android:text="读取" />

</LinearLayout>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="horizontal">

<EditText
android:id="@+id/et2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="外部输入内容"
android:inputType="textPersonName" />

<Button
android:id="@+id/bt3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="outsave"
android:text="外部保存" />

<Button
android:id="@+id/bt4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="outread"
android:text="外部读取" />
</LinearLayout>

</LinearLayout>

Activity

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
package com.example.file;

import androidx.appcompat.app.AppCompatActivity;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import static android.os.Environment.MEDIA_MOUNTED;

public class MainActivity extends AppCompatActivity {
TextView et, et2;

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

public void save(View v) throws Exception {
String name = "hello.txt";
String data = et.getText().toString();
FileOutputStream out = openFileOutput(name, Context.MODE_PRIVATE);
out.write(data.getBytes());
out.close();
Toast.makeText(this, "数据写入成功", Toast.LENGTH_SHORT).show();
}

public void read(View v) throws IOException {
String name = "hello.txt";
FileInputStream input = openFileInput(name);
byte[] buffer = new byte[input.available()];
input.read(buffer);
String content = new String(buffer);
input.close();
Log.e("输出", content);
et.setText(content);
Toast.makeText(this, "读取成功", Toast.LENGTH_SHORT).show();
}

public void outsave(View v) throws Exception {

String name = "hello.txt";
String data = et2.getText().toString();
String state = Environment.getExternalStorageState();
//判断SD卡是否可用
if (MEDIA_MOUNTED.equals(state)) {
File SDPath = Environment.getExternalStorageDirectory();
//获取SD卡路径
File file = new File(SDPath, name);
FileOutputStream out = new FileOutputStream(file);
out.write(data.getBytes());
out.close();
Toast.makeText(this, "外部数据写入成功", Toast.LENGTH_SHORT).show();
}
}

public void outread(View v) throws IOException {
String name = "hello.txt";
String state = Environment.getExternalStorageState();
//判断SD卡是否可用
if (MEDIA_MOUNTED.equals(state)) {
File SDPath = Environment.getExternalStorageDirectory();
//获取SD卡路径
File file = new File(SDPath, name);
FileInputStream input = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(input));
String content = br.readLine();
input.close();
Log.e("输出", content);
et2.setText(content);
Toast.makeText(this, "外部读取成功", Toast.LENGTH_SHORT).show();
}
}
}

manifest配置

注意:由于安卓的安全策略,需要添加读写权限

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
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.example.file">
<dist:module dist:instant="true" />
//添加sd卡读权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
//添加sd卡写权限
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

结果

点击保存后会看到应用目录内新建了一个txt

data/data/对应包内/·

打开txt可以看到添加的字符串

点击保存后会看到sd目录内新建了一个txt(不同手机可能会不同)

sdcard/·