•前言

  任何一个应用程序,其实说白了就是在不停地和数据打交道,我们聊QQ、看新闻、刷微博,所关心的都是里面的数据,

  没有数据的应用程序就变成了一个空壳子,对用户来说没有任何实际用途。

  那么这些数据都是从哪来的呢?

  现在多数的数据基本都是由用户产生的,比如你发微博、评论新闻,其实都是在产生数据。

  什么是瞬时数据呢?

  就是指那些存储在内存当中,有可能会因为程序关闭或其他原因导致内存被回收而丢失的数据。

  这对于一些关键性的数据信息来说是绝对不能容忍的,谁都不希望自己刚发出去的一条微博,刷新一下就没了吧。

  那么怎样才能保证一些关键性的数据不会丢失呢?这就需要用到数据持久化技术了。

•持久化技术简介

  数据持久化就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失。

  保存在内存中的数据是处于瞬时状态的,而保存在存储设备中的数据是处于持久状态的,

  持久化技术则提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换。

  Android系统中主要提供了 3种 方式用于简单地实现数据持久化功能,即文件存储、SharedPreference存储以及数据库存储。

•文件存储

  文件存储是 Android 中最基本的一种数据存储方式,它不对存储的内容进行任何的格式化处理,

  所有数据都是原封不动地保存到文件当中的,因而它比较适合用于存储一些简单的文本数据或二进制数据。

  如果你想使用文件存储的方式来保存一些较为复杂的文本数据,就需要定义一套自己的格式规范,这样可以方便之后将数据从文件中重新解析出来。

  那么首先我们就来看一看,Android 中是如何通过文件来保存数据的。

•将数据存储到文件中

  在学习本次内容前,你要先学会 Java 中的 IO 流,鄙人不才,写了一篇关于 IO 流的博客,毛遂自荐一下;

  接下来,创建一个 TestFilePersistence 项目,并修改 activity_main.xml 中的代码;

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="10dp"> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="现在是瞬时数据"
android:textSize="20sp" /> <EditText
android:id="@+id/edit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="type something here" /> </LinearLayout>

  这里在布局中加入了一个 EditText,用于输入文本内容。

  现在运行一下程序了,界面上有一个文本输入框,然后在文本输入框中随意输入点什么内容,按下 Back 键,在打开,

  这时输人的内容肯定就已经丢失了,因为它只是瞬时数据,在活动被销毁后就会被回收。

运行效果

  

  而这里我们要做的,就是在数据被回收之前,将它存储到文件当中。

  Context类中提供了一个  openFileOutput()  方法,可以用于将数据存储到指定的文件中。

  这个方法接收两个参数:

  • 第一个参数是文件名,在文件创建的时候使用的就是这个名称

    • 注意这里指定的文件名不可以包含路径
    • 因为所有的文件都是默认存储到  /data/data/<package name>/files/  目录下的
  • 第二个参数是文件的操作模式,主要有两种模式可选

    • MODE_PRIVATE 和 MODEAPPEND
    • 其中 MODEPRIVATE 是默认的操作模式,表示当指定同样文件名的时候所写入的内容将会覆盖原文件中的内容
    • 而 MODEAPPEND 则表示如果该文件已存在,就往文件里面追加内容,不存在就创建新文件

  其实文件的操作模式本来还有另外两种:

  • MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE
  • 这两种模式表示允许其他的应用程序对我们程序中的文件进行读写操作
  • 不过由于这两种模式过于危险,很容易引起应用的安全性漏洞,已在Android4.2版本中被废弃

   openFileOutput()  方法返回的是一个 FileOutputStream 对象,得到了这个对象之后就可以使用 Java流 的方式将数据写入到文件中了。

  接下来通过代码做个简单示例。

  修改 MainActivity.java 中的代码;

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private EditText edit;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); edit = findViewById(R.id.edit);
} @Override
protected void onDestroy() {
super.onDestroy();
try {
save(getData());
} catch (IOException e) {
e.printStackTrace();
}
} public String getData(){
return edit == null ? null:edit.getText().toString();
} public void save(String data) throws IOException{
//IO流常规操作
FileOutputStream out = openFileOutput("data.txt",Context.MODE_PRIVATE);
out.write(data.getBytes());
out.close();
}
}

  可以看到,首先我们在  onCreate()  方法中获取了 EditText 的实例,然后重写了  onDestroy()  方法,

  这样就可以保证在活动销毁之前一定会调用这个方法。

  在  onDestroy()  方法中调用  save()  方法把输入的内容存储到文件中,文件命名为data。

  现在重新运行一下程序,并在 EditText 中输入一些内容;

  然后按下 Back键 关闭程序,这时我们输入的内容就已经保存到文件中了。

  那么如何才能证实数据确实已经保存成功了呢?我们可以借助 Android Device Monitor 工具来查看一下。

Android Device Monitor

  点击上方工具栏中的【Tools】,并在下拉菜单中选择【SDK Manager】;

  再弹出的界面中找到【Android SDK】;

  右侧会出现【Android SDK】的存储路径,找到该路径所表示的文件;

  依次点击【tools】->【lib】->【monitor-x86_64】;

  

  在弹出的界面中双击【monitor.exe】

  这个就是 Android Device Monitor;

  找到 Android Device Monitor 工具后,进入 File Explorer 标签页,在这里找到

data/data/com.example.testfilepersistence/files

  目录,可以看到,在该目录中生成了一个 data.txt 文件;

  选中该文件,并点击右上角红框框处的按钮,将该文件导出到电脑上,并查看该文件的内容;

  这样就证实了,在 EditText 中输入的内容确实已经成功保存到文件中了。

  不过只是成功将数据保存下来还不够,我们还需要想办法在下次启动程序的时候让这些数据能够还原到EditText中,

  因此接下来我们就要学习一下如何从文件中读取数据。

•从文件中读取数据

  类似于将数据存储到文件中,Context 类中还提供了一个  openFileInput()  方法,用于从文件中读取数据。

  这个方法要比  openFile0utput()  简单一些,它只接收一个参数,即要读取的文件名,

  然后系统会自动到  /data/data/<package name>/files/  目录下去加载这个文件,并返回一个FileInputStream对象,

  得到了这个对象之后再通过 Java流 的方式就可以将数据读取出来了。

  修改 MainActivity.java 中的代码;

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private EditText edit;

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); edit = findViewById(R.id.edit); try {
String s = read();
edit.setText(s);
edit.setSelection(s.length());//将输入光标移动到文档末尾
Toast.makeText(this,"读取成功",Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
protected void onDestroy() {...} public String getData(){...} public void save(String data) throws IOException{...} public String read() throws IOException{
FileInputStream in = openFileInput("data.txt");
byte[] b = new byte[100];
String s = "";
int x = 0;
while((x = in.read(b)) != -1){
s += new String(b,0,x);
}
return s;
}
}

  在  read()  方法中,首先通过  openFileInput()  方法获取到了一个 FileInputStream 对象,

  我们就可以通过 FileInputStream 进行读取,把文件中所有的文本内容全部读取出来,并存放在一个 String 对象中;

  最后将读取到的内容返回就可以了。

运行结果

  

Android学习之文件存储的更多相关文章

  1. Android入门(九)文件存储与SharedPreferences存储

    原文链接:http://www.orlion.ga/578/ Android系统中主要提供了三种方式用于简单地实现数据持久化功能,即文件存储.SharedPreference存储以及数据库存储.当然, ...

  2. Android学习总结——文件储存

    Android中文件存储的操作: 1.Activity的openFileOutput()方法可以把数据输出到文件中2.创建的文件保存在/data/data/<package name>/f ...

  3. kafka学习之-文件存储机制

    Kafka是什么 Kafka是最初由Linkedin公司开发,是一个分布式.分区的.多副本的.多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx ...

  4. android之外部文件存储和读取

    这次借用上次读写内部存储的代码,只是对将更换文件的读写路径即可.这里需要对获取SDcard的读写权限. 一.AndroidManifest.xml 这里增加了对外部存储设备的读写权限 <?xml ...

  5. Android——手机内部文件存储(作业)

    作业:把用户的注册信息存储到文件里,登录成功后读出并显示出来 activity_practice2的layout文件: <?xml version="1.0" encodin ...

  6. Android学习笔记——文件路径(/mnt/sdcard/...)、Uri(content://media/external/...)学习

    一.URI 通用资源标志符(Universal Resource Identifier, 简称"URI"). Uri代表要操作的数据,Android上可用的每种资源 - 图像.视频 ...

  7. android面试(4)---文件存储

    1.sharePreference? SharedPreferences类,它是一个轻量级的存储类,特别适合用于保存软件配置参数. SharedPreferences保存数据,其背后是用xml文件存放 ...

  8. Android学习笔记——文件路径、内容Uri学习笔记[转]

    一.URI 通用资源标志符(Universal Resource Identifier, 简称"URI"). Uri代表要操作的数据,Android上可用的每种资源 - 图像.视频 ...

  9. android中的文件存储

    Context类中提供的IO方法: FileOutputSream openFileOutput(String name, int mode):打开应用程序中的/data/data/<应用程序的 ...

  10. Android_文件存储

    因为项目的需求,想实现一个指导使用的欢迎页效果,通过在网上的询问,给的一种解决办法是通过SharedPreferences文件存储方式来实现,具体的实现类似于通过第一次取得SharedPreferen ...

随机推荐

  1. vs不同版本支持的c++版本和PlatformToolset,及在vs中切换c++版本

    找c++资料从网上找确实更快速,但要想深入地理解vc++建议看msdn文档. vs不同版本支持的c++版本 C++17: vs2017基本支持,vs2015部分支持. C++14: vs2017就可以 ...

  2. PGL图学习项目合集&数据集分享&技术归纳业务落地技巧[系列十]

    PGL图学习项目合集&数据集分享&技术归纳业务落地技巧[系列十] 1.PGL图学习项目合集 1.1 关于图计算&图学习的基础知识概览:前置知识点学习(PGL)[系列一] :ht ...

  3. 【编写环境二】python库scipy.stats各种分布函数生成、以及随机数生成【泊松分布、正态分布等】

    平时我们在编写代码是会经常用到一些随机数,而这些随机数服从一定的概率分布. 1.泊松分布.正态分布等生成方法 1.1常见分布: stats连续型随机变量的公共方法: *离散分布的简单方法大多数与连续分 ...

  4. SpringCloud-Gateway搭建保姆级教程

    一.网关介绍 1.什么是网关? 使⽤服务⽹关作为接⼝服务的统⼀代理,前端通过⽹关完成服务的统⼀调⽤ 2.⽹关可以⼲什么? 路由:接⼝服务的统⼀代理,实现前端对接⼝服务的统⼀访问 过滤:对⽤户请求进⾏拦 ...

  5. 使用KVM创建OEL虚拟机

    在Linux工作站上使用KVM创建虚拟机. 首先说下我的需求: 1.其他LAN内的笔记本也可以连接到这些KVM的虚拟机,因此需要配置使用桥接网络 2.创建一个虚拟机,采用最小化安装系统,作为基础模版, ...

  6. .NET Core开发实战(第34课:MediatR:轻松实现命令查询职责分离模式(CQRS))--学习笔记(下)

    34 | MediatR:轻松实现命令查询职责分离模式(CQRS) 实际上我们在定义我的查询的时候,也可以这样定义,例如我们定义一个 MyOrderQuery,把订单的所有名称都输出出去 namesp ...

  7. .NET Core开发实战(第12课:配置变更监听)--学习笔记

    12 | 配置变更监听:配置热更新能力的核心 这一节讲解如何使用代码来监视配置变化并做出一些动作 当我们需要追踪配置发生的变化,可以在变化发生时执行一些特定的操作 配置主要提供了一个 GetReloa ...

  8. 从零开始的react入门教程(三),了解react事件与使用注意项

    壹 ❀ 引 在从零开始的react入门教程(二),从react组件说到props/state的联系与区别一文中,我们介绍了react组件的基本用法以及props与state的区别.其中react组件分 ...

  9. JS leetcode 合并两个有序数组 解题分析

    壹 ❀ 引 今天做的一题是前两周博客园一粉丝在面试360时遇到的算法题,题目来自leetcode88. 合并两个有序数组,理解起来可能有些费劲,不过我尽量用图的形式给大家解释它,题目描述如下: 给你两 ...

  10. NC22598 Rinne Loves Edges

    题目链接 题目 题目描述 Rinne 最近了解了如何快速维护可支持插入边删除边的图,并且高效的回答一下奇妙的询问. 她现在拿到了一个 n 个节点 m 条边的无向连通图,每条边有一个边权 \(w_i\) ...