持久化技术简介
数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或计算机关机的情况下,这些数据仍然不会丢失。
保存在内存中的数据是处于瞬时状态的,而保存在存储设备中的数据是处于持久状态的。持久化技术提供了一种机制,可以让数据在瞬时状态和持久状态之间进行转换。
Android系统中主要提供了3种方式用于简单地实现数据持久化功能:
文件存储、SharedPreferences存储、数据库存储。
第一种方式:文件存储
文件存储是Android中最基本的数据存储方式,它不对存储的内容进行任何格式化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合存储一些简单的文本数据或二进制数据。
如果你想使用文件存储的方式来保存一些较为复杂的结构化数据,就需要定义一套自己的格式规范,方便之后将数据从文件中重新解析出来。
将数据存储到文件中
Context类中提供了一个openFileOutput()方法,可以用于将数据存储到指定的文件中。
所有的文件会默认存储到/data/data//files/目录下。示例写法如下:
fun save(inputText: String) { try { val output = openFileOutput("data", Context.MODE_PRIVATE) val writer = BufferedWriter(OutputStreamWriter(output)) writer.use { it.write(inputText) } } catch (e: IOException) { e.printStackTrace() } }
Context 类中提供了一个openFileOutput( )方法,让我们可以将数据存储在指定位置,该文件接收两个参数,第一个是文件名,第二个是文件的操作模式,主要有MODE_PRIVATE(默认的,有覆盖内容的作用)和MODE_APPEND(不覆盖但有追加和创建作用)两种。
代码分析:
- 通过一个openFileOutput( )方法得到FileOutputStream对象-output
- 借助output构建出OutputStreamWriter对象
- 使用OutputStreamWriter构建BufferedWriter对象-writer
- 这样就可以通过BufferedWriter把内容写入文件,最后使用kotlin提供的内置扩展函数use自动将外层的流关闭。
从文件中读取数据
Context类中还提供了一个openFileInput()方法,用于从文件中读取数据。
它会自动到/data/data//files/目录下加载文件,并返回一个FileInputStream对象,得到这个对象之后,再通过流的方式就可以将数据读取出来了。示例写法如下:
fun load(): String { val content = StringBuilder() try { val input = openFileInput("data") val reader = BufferedReader(InputStreamReader(input)) reader.use { reader.forEachLine { content.append(it) } } } catch (e: IOException) { e.printStackTrace() } return content.toString() }
代码分析:
- 通过一个openFileInput( )方法得到FileOutputStream对象-intput
- 借助intput构建出InputStreamReader对象
- 使用InputStreamReader构建BufferedReader对象-reader
- 这样就可以通过BufferedReader把内容读取文件
- 再拼接到StringBuilder对象中,最后把读取的内容返回
6.函数use可自动将外层的流关闭,并在其中使用forEachLine函数,他会将读取的内容回调到Lambda表达式中
案例-文件存储技术
MainActivity.kt
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //1.在onCreate()方法中调用load()方法读取文件中存储的内容 val inputText = load() //如果不为空,就调用EditText的setText()方法将内容填充到 EditText中 if (inputText.isNotEmpty()) { editText.setText(inputText) //再调用setSelection()方法将输入光标移动到文末以便继续输入 editText.setSelection(inputText.length) //然后弹出还原成功的Toast提示 Toast.makeText(this, "还原成功", Toast.LENGTH_SHORT).show() } } //重写onDestroy()方法,保证Activity在销毁之前一定会用到的方法 override fun onDestroy() { super.onDestroy() //获取EditText中输入的内容 val inputText = editText.text.toString() //调用save()方法将内容存储到文件中 save(inputText) } private fun save(inputText: String) { try { val output = openFileOutput("data", Context.MODE_PRIVATE) val writer = BufferedWriter(OutputStreamWriter(output)) writer.use { it.write(inputText) } } catch (e: IOException) { e.printStackTrace() } } private fun load(): String { val content = StringBuilder() try { val input = openFileInput("data") val reader = BufferedReader(InputStreamReader(input)) reader.use { reader.forEachLine { content.append(it) } } } catch (e: IOException) { e.printStackTrace() } return content.toString() } }
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Type something here" /> </LinearLayout>
总结: 核心技术就是openFileInput()和 openFileOutput()方法。