目录

文件存储

保存数据

保存输入框中的数据

读取数据

SharedPreferences存储

获取SharedPreferences对象

使用SharedPreferences保存数据

读取SharedPreferences数据

SQLite数据库存储


文件存储

文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式 化处理,所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据

  • Context.openFileOutput(): 可以用于将数据存储到指定的文件中。 这个方法接收两个参数,第一个参数是文件名,在文件创建的时候使用的就是这个名称,注意这里指定的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data//files/目录下的第二个参数是文件操作模式,主要两种模式可选,MODE_PRIVATE和MODE_APPEND。其中MODE_PRIVATE 是默认的操作模式,表示当指 定同样文件名的时候,所写入的内容将会覆盖原文件中的内容,而 MODE_APPEND表示如果该文件存在就往文件里面追加内容,不存在就创建新文件。

保存数据

一个简单的例子存储数据:

package com.example.test;import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);save();}public void save() {String data = "Something need to be saved";FileOutputStream fileOutputStream = null;BufferedWriter bufferedWriter = null;try {//saveData为文件名, Mode_PRIVATE是默认的操作模式,即内容直接覆盖fileOutputStream = openFileOutput("savedData", MODE_PRIVATE);//将字节流转换为字符留,然后利用该字符流新建一个缓冲字符流bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));//写入数据bufferedWriter.write(data);} catch (IOException e) {e.printStackTrace();} finally {//关闭资源try {if (null != bufferedWriter) {bufferedWriter.close();}} catch (IOException e) {e.printStackTrace();}}}
}

运行后结果如下,可见在android文件系统里已经保存了相应的数据:

保存输入框中的数据

Context 类中还提供了一个 openFileInput()方法,用于从文件中读取数据。这个方法要比 openFileOutput()简单一些,它只接收一个参数,即要读取的文件名,然后系统会自动到/data/data//files/目录下去加载这个文件,并返回一个 FileInputStream 对象,得到了这个对象之后再通过 Java 流的方式就可以将数据读取出来了

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/input"android:hint="Input something here"/></LinearLayout>

MainActivity.java

package com.example.test;import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;public class MainActivity extends AppCompatActivity {private static final String TAG = "MainActivity";EditText editText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText = (EditText) findViewById(R.id.input);}@Overrideprotected void onDestroy() {super.onDestroy();// 活动销毁时保存数据String data = String.valueOf(editText.getText());save(data);}public void save(String data) {FileOutputStream fileOutputStream = null;BufferedWriter bufferedWriter = null;try {//saveData为文件名, Mode_PRIVATE是默认的操作模式,即内容直接覆盖fileOutputStream = openFileOutput("savedData", MODE_PRIVATE);//将字节流转换为字符留,然后利用该字符流新建一个缓冲字符流bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));//写入数据bufferedWriter.write(data);} catch (IOException e) {e.printStackTrace();} finally {//关闭资源try {if (null != bufferedWriter) {bufferedWriter.close();}} catch (IOException e) {e.printStackTrace();}}}
}

读取数据

package com.example.test;import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;public class MainActivity extends AppCompatActivity {private EditText editText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText = findViewById(R.id.input);String data = load();   //加载数据if (!data.isEmpty()) {editText.setText(data); //恢复数据editText.setSelection(data.length());Toast.makeText(this, "restored data successfully", Toast.LENGTH_LONG).show();}}@Overrideprotected void onDestroy() {super.onDestroy();// 活动销毁时保存数据String data = String.valueOf(editText.getText());save(data);}//save datapublic void save(String data) {FileOutputStream fileOutputStream;BufferedWriter bufferedWriter = null;try {//saveData为文件名, Mode_PRIVATE是默认的操作模式,即内容直接覆盖fileOutputStream = openFileOutput("savedData", MODE_PRIVATE);//将字节流转换为字符留,然后利用该字符流新建一个缓冲字符流bufferedWriter = new BufferedWriter(new OutputStreamWriter(fileOutputStream));//写入数据bufferedWriter.write(data);} catch (IOException e) {e.printStackTrace();} finally {//关闭资源try {if (null != bufferedWriter) {bufferedWriter.close();}} catch (IOException e) {e.printStackTrace();}}}//load datapublic String load() {FileInputStream fileInputStream;BufferedReader bufferedReader = null;StringBuilder data = new StringBuilder();try {fileInputStream = openFileInput("savedData");bufferedReader = new BufferedReader(new InputStreamReader(fileInputStream));//每次读取一行String line;while (( line = bufferedReader.readLine()) != null) {data.append(line);}} catch (IOException e) {e.printStackTrace();} finally {if (bufferedReader != null) {try {bufferedReader.close();} catch (IOException e) {e.printStackTrace();}}}return data.toString();}
}

文件存储所用到的核心技术就是Context类中提供的openFileInput()和openFileOutput()方法,之后就是利用各种IO流来进行读写操作。 不过,正如我前面所说,文件存储的方式并不适合用于保存一些较为复杂的结构型数据。

SharedPreferences存储


获取SharedPreferences对象

使用SharedPreferences来存储数据,首先需要获取到SharedPreferences对象。Android 中主要提供了三种方法用于得到 SharedPreferences 对象。

  1. Context 类中的 getSharedPreferences()方法
    此方法接收两个参数,第一个参数用于指定 SharedPreferences 文件的名称,如果指定文件不存在则会创建一个,SharedPreferences文件存放在/data/data//shared_prefs/目录。第二个用于指定操作模式,主要有两种模式,MODE_PRIVATE 和 MODE_MULTI_PROCESS。MODE_PRIVATE 是默认操作模式,和直接传入0效果相同,表示只有当前的应用程序才可以对这个 SharedPreferences文件进行读写。MODE_MULTI_PROCESS 则一般是用于会有多个进程中对同一个SharedPreferences文件进行读写的情况
  2. Activity 类中的 getPreferences()方法
    这个方法和 Context 中的 getSharedPreferences()方法很相似,不过它只接收一个操作模式参数,因为使用这个方法时会自动将当前活动的类名作为 SharedPreferences 的文 件名。
  3. PreferenceManager 类中的 getDefaultSharedPreferences()方法
    这是一个静态方法,它接收一个 Context 参数,并自动使用当前应用程序的包名作为前缀来命名 SharedPreferences 文件

使用SharedPreferences保存数据

主要可以分为三步实现:

  1. 调用 SharedPreferences 对象的 edit()方法来获取一个 SharedPreferences.Editor 对象。
  2. 向 SharedPreferences.Editor 对象中添加数据,比如添加一个布尔型数据就使用 putBoolean 方法,添加一个字符串则使用 putString()方法,以此类推。
  3. 调用 commit()方法将添加的数据提交,从而完成数据存储操作。

下面看一个例子:

更改activity_main.xml,不做任何复杂的功能,只是简单地放置了一个按钮,用于将一些数据存储到 SharedPreferences 文件当中。

<?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"tools:context=".MainActivity"><Buttonandroid:id="@+id/save_data"android:text="Save Data"android:textSize="40dp"android:textAllCaps="false"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginTop="350dp"/></LinearLayout>

MainActivity.java 

package com.example.sharedpreferencestest;import androidx.appcompat.app.AppCompatActivity;import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button buttonSavedData = findViewById(R.id.save_data);buttonSavedData.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {SharedPreferences.Editor editor = getSharedPreferences("savedData",MODE_PRIVATE).edit();//添加一些数据(键值对的形式)editor.putString("name", "zhoufuming");editor.putInt("age", 25);editor.putBoolean("married", false);//提交数据editor.commit();}});}
}

运行代码,界面显示如下: 

点击Save Data按钮后,查看系统内部,出现了文件savedData.xml文件,内容也正是所输入的。

读取SharedPreferences数据

SharedPreferences 对象中提供了一系列的get方法用于对存储的数据进行读取,每种get方法都对应了SharedPreferences. Editor中的一种 put 方法,比如读取一个布尔型数据就使用getBoolean()方法,读取一个字符串就使用 getString()方法。这些getXXX方法都接收两个参数,第一个参数是键,传入存储数据 时使用的键就可以得到相应的值了,第二个参数是默认值,即表示当传入的键找不到对应的值时,会以什么样的默认值进行返回。

在 SharedPreferencesTest 项目的基础上修改 activity_main.xml 中的代码,增加了一个读取数据的按钮,如下所示:

<?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="horizontal"tools:context=".MainActivity"><Buttonandroid:id="@+id/save_data"android:text="Save Data"android:textSize="20dp"android:textAllCaps="false"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="20dp"/><Buttonandroid:id="@+id/read_data"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="60dp"android:text="Read Data"android:textAllCaps="false"android:textSize="20dp"/></LinearLayout>

布局如下图所示:

然后更改MainActivity.java中的代码,如下所示:

运行程序,然后点击Read_Data的按钮,可以观察到打印如下:

SQLite数据库存储

SQLite 不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要你以前使用过其他的 关系型数据库,就可以很快地上手 SQLite。文件存储和SharedPreferences存储只适用于去保存一些简单的数据和键值对,SQLite用于需要存储大量复杂的关系型数据的时候。

运用SQLite保存数据

数据存储方案(一) - 文件存储、SharedPreferences存储相关推荐

  1. 树莓派存储方案_树莓派搭建seafile存储重要文件

    谈到NAS,我个人需求主要是: 下电影以及看电影 保存重要文件,例如:照片,工作文档. 然而大多数人一提到NAS,就会想上X86架构,比如最近很火的蜗牛星际. 然而X86架构功耗高,噪音大,用作NAS ...

  2. 【Android 文件管理】分区存储 ( 分区存储机制 和 文件索引数据 )

    文章目录 一.Android 10 以前的存储机制 二.Android 10 及以后的分区存储机制 三.Android 10 中的存储过渡方案 四.文件索引数据库 五.相关文档资料 一.Android ...

  3. 数据存储在.csv文件乱码,数据写入才一部分就报错'gbk' codec can't encode character '\xee' in position 45: illegal multibyte

    使用python爬虫爬取规则数据后转化成来List格式,将其存储在.csv 文件中 使用Python写文件的时候,或者将网络数据流写入到本地文件的时候,大部分情况下会遇到:UnicodeEncodeE ...

  4. IOS数据存储之文件沙盒存储

    前言: 之前学习了数据存储的NSUserDefaults,归档和解档,对于项目开发中如果要存储一些文件,比如图片,音频,视频等文件的时候就需要用到文件存储了.文件沙盒存储主要存储非机密数据,大的数据. ...

  5. COS云存储有哪些优势?基于EasyCVR平台的两种监控视频数据存储方案

    随着物联网.AI.云计算.大数据等新兴技术的发展.海量设备的接入.视频质量的不断提升,监控视频存储也面临着巨大的挑战.当前用户对视频监控数据的存储问题,主要考虑到以下三个因素: 1)数据的安全性和稳定 ...

  6. 系统中的文件存储方案

    项目中经常要用到文件存储 方案1: 文件传给后端,后端存到本地,当静态资源 方案2: 文件传给后端,后端上传到文件服务器(如minio) 方案3: 前端从后端获取到文件服务器的账户和密码,然后前端直接 ...

  7. 存储服务器在监控中的作用,监控项目中存储服务器IPSAN云存储方案的优劣势对比...

    <监控项目中存储服务器IPSAN云存储方案的优劣势对比>由会员分享,可在线阅读,更多相关<监控项目中存储服务器IPSAN云存储方案的优劣势对比(4页珍藏版)>请在人人文库网上搜 ...

  8. 【重识云原生】第三章云存储3.5节——商用分布式云存储方案

    <重识云原生系列>专题索引: 第一章--不谋全局不足以谋一域 第二章计算第1节--计算虚拟化技术总述 第二章计算第2节--主流虚拟化技术之VMare ESXi 第二章计算第3节--主流虚拟 ...

  9. mysql 存储引擎接口_MySQL体系结构和存储引擎

    数据库与传统文件系统最大的区别在于数据库是支持事务的 一.定义数据库与实例 1.数据库: 物理操作系统的文件或者其他文件类型的集合,依照某种数据模型组织起来并存储于二级存储器中的数据集合. 2.实例: ...

最新文章

  1. Java排序算法:冒泡排序
  2. PAT甲级1150 Travelling Salesman Problem:[C++题解]旅行商问题、图论
  3. 在 Windows 上直接运行 Linux,有命令行就是贼香
  4. 和同学沟通,一定是时间效率比较高的
  5. Faster-RCNN算法精读
  6. 用scikit-learn进行LDA降维(转载+注释)
  7. vue实现侧边折叠菜单栏手风琴效果
  8. php tp写构造函数,详细介绍ThinkPHP中类的构造函数_construct()与_initialize()的区别
  9. vue $ 符号(例如vm.$data vs vm.data):读取实例属性 vs 读取 data 数据
  10. conda创建环境速度慢解决办法
  11. 联想e470c怎么修改电脑语言,联想电脑语言切换不了怎么办
  12. 微信小程序(一):微信小程序与服务器的简单链接
  13. HTTP Security Header Not Detected
  14. 计算机数控入门,数控车床入门教程 如何进入CNC加工过程
  15. 机器学习模型中的评价指标
  16. 去除Ninja的提醒
  17. 人工智能笔记 2.1人工智能导论- 1.什么是AI,深度优先,广度优先,最优路径
  18. 最新表白墙网站源码 手机电脑自适应 带后台
  19. 马云的又一招棋,平台基因怎么让飞猪成为出境游领军者
  20. DHCP 中继Snooping解释以及配置

热门文章

  1. modern php_使用Modern.IE改善WordPress主题开发
  2. Dundas Map for ASP.NET 最新版下载试用2021版本
  3. 联想服务器sr650硬件配置表,ThinkSystem SR650规格解读_联想 System x3650 M4_服务器x86服务器-中关村在线...
  4. 用UDP网络编程做简易聊天工具
  5. 城市商业传说:打飞的吗?无人的那种
  6. 曝光骗子QQ1052073458
  7. 计算机设计压力容器过程,压力容器及过程设备设计
  8. 中国大学MOOC课程《Python语言程序设计》第五章 七段数码管绘制 引发的时间问题和海龟速度问题
  9. win10系统轻量级垃圾清理软件推荐
  10. 打开html文件原理,为什么一个html文件在别人的电脑上显示这样的?