本文正在参加「金石计划 . 分割6万现金大奖」

前言

上一篇咱们简略的了解了安卓数据存储并初识了文件存储这个技术(Re:从零开始的安卓数据存储学习生活(开篇) – ())。本篇将进一步看看文件存储是怎么用的。

正篇

概述

其实文件存储是安卓中最根本的数据存储办法,所以说它原汁原味也不过火,它不会对存储的内容进行任何格局化处理,用它存储的数据都是原封不动的保存在文件中。
但这样也就使得这种办法更适合存储一些比较简略的文本数据或是二进制数据,其实如果真的想用文件存储的办法去保存一些比较杂乱的结构化数据,也能够定义一套自己的格局标准,以便利将数据从文件中再次解析出来。
本篇使用一个完整的比如来阐明文件存储的一些根本用法,暂不对相关杂乱存储阐明。

存文件

本比如是经过文件存储输入框输入的内容来实现下次重新启动APP的输入框中依然能够显现所输入内容,这也是咱们很多APP上体现的输入历史记录相同,不过我在事务中一般仍是用数据存储的第二种办法-SharedPreferences存储。

咱们首先在activity_main.xml布局中增加一个EditText,作为咱们的输入框用来输入存储内容,代码如下:

<EditText
    android:id="@+id/editText"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:hint="Please write something here"
    />

接着在onDestroy()办法中咱们调用save()办法,save()办法即咱们使用文件存储存入数据的办法,这样咱们就能在Activity完毕前把咱们输入的东西存入文件中,代码如下:

override fun onDestroy() {
    super.onDestroy()
    val inputText = editText.text.toString()
    save(inputText)
}
private fun save(inputText : String) {
    try {
        val output = openFileOutput("data", Context.MODE_PRIVATE)
        val write = BufferedWriter(OutputStreamWriter(output))
        write.use {
            it.write(inputText)
        }
    } catch (e : IOException) {
        e.printStackTrace()
    }
}

这个时分咱们能够在AS的Device File Explorer中找到文件,如下图:

原汁原味的安卓文件存储(数据存储系列)

在/data/data/com.example.filepersistencetest找到data文件

原汁原味的安卓文件存储(数据存储系列)
原汁原味的安卓文件存储(数据存储系列)

打开后能够看到就是刚刚退出Activity时分输入的数据,阐明文件已经成功保存。

原汁原味的安卓文件存储(数据存储系列)

取出数据

对应的咱们也需求在用的时分再次取出数据,所以咱们需求使用Context类中供给的另一个办法-openFileInput()办法,使用办法如下,咱们将其封装为load办法用于在onCreate办法调用,这样打开的APP就能获取到之前输入的数据并加载出来:

//取出文件中所保存内容
private fun load() : String {
    //把文件取出的数据一行行拼接在StringBuilder目标当中,用于返回内容(String)
    val content = StringBuilder()
    try {
        //获取FileInputStream目标
        val input = openFileInput("data")
        //构建BufferedReader目标
        val reader = BufferedReader(InputStreamReader(input))
        //读取文件内容
        reader.use {
            //Kotlin供给的一个内置扩展函数,能够将读到的每行内容都回调到Lambda表达式中,然后在Lambda表达式中完成拼接逻辑
            reader.forEachLine {
                content.append(it)
            }
        }
    } catch (e: IOException) {
        e.printStackTrace()
    }
    return content.toString()
}

该办法接受要读取的文件名作为参数,系统自动到/data/data/<package name>/files目录下加载对应文件,返回FileInputStream目标,咱们再经过流的办法就能够将数据读取出来。

原汁原味的安卓文件存储(数据存储系列)
onCreate办法中调用的代码:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val inputText = load()
    //数据不为空则将内容填充到EditText中
    if (inputText.isNotEmpty()) {
        editText.setText(inputText)
        //光标(焦点)位置移到文字末
        editText.setSelection(inputText.length)
        //复原成功提示
        Toast.makeText(this, "Restoring succeeded", Toast.LENGTH_SHORT).show()
    }
}

总结

文件存储不太适合保存比较杂乱的结构型数据,下一篇将讨论一下我感觉更重要的Sp存储,这个存储办法真的在工作中频繁用到,谢谢各位观看,敬请期待下一篇!