46. 【Android教程】文件存储

news2024/11/17 8:40:58

Android 提供了很多种存储的数据的方式,比如“Shared Preferenced”、“文件”、“SQLite”、“远端”等等。其中最直接的就是文件存储,本节就来看看如果通过文件的方式持久化我们的数据。

1. 文件存储的特点

文件存储是最好理解的一种方式,类似“新建文件夹”然后“创建文件”,最后直接把数据写到对应文件中即可。考虑到文件的安全性,Android 为每个 App 都分配了一个私有文件读取权限,也就是每个 App 创建的私有文件只有自己的 App 才有权限访问,就极大的保护了用户的隐私安全。

2. 文件存储的相关方法

文件操作基本上就是做文件 I/O,围绕输入输出主要提供了以下方法:

  • openFileInput(String fileName):
    打开文件输入流,获取文件中的信息
  • openFileOutput(String fileName, int mode):
    以某种模式打开文件输出流,将信息输出到文件中
  • getDir(String fileName, int mode):
    创建或者获取(取决于是否存在)文件名为 fileName 的文件,并存储在 App 的私有目录(data目录)下
  • getFileDir():
    获取 App 私有目录(data目录)文件对应的绝对路径
  • deleteFile(String fileName):
    不必多解释,删除目录
  • String[] fileList():
    获取目录下的全部文件,返回全部文件列表

3. 文件 I/O 操作

3.1 文件输出

通过调用openFileOutput()来获取一个文件输出流,然后将数据写入输出流从而最终保存到对应的文件中。在第 2 小节提到过,openFileOutput()有一个 mode 参数,它可以设置成

  • MODE_PRIVATE:私有文件,仅支持当前 App 访问
  • MODE_WORLD_READABLE:除了当前 App,仅支持可读权限
  • MODE_WORLD_WRITEABLE:其他 App 可写
  • MODE_APPEND:文件内容追加,默认是会覆盖
    该方法返回一个文件输出流实例,之后便可以通过输入流实例来向文件写数据了,代码示例如下:
FileOutputStream out = openFileOutput("file name here",MODE_WORLD_READABLE);
String str = "data";
out.write(str.getBytes());
out.close();

3.2 文件输入

通过openFileInput()可以读取我们刚刚创建的文件,和FileOutputStream方法类似,该方法返回一个输入流,接着我们可以从输入流里读取数据,代码示例如下:

FileInputStream in = openFileInput(file);
int c;
String temp="";
// 挨个读取字符
while( (c = in.read()) != -1){
   temp = temp + Character.toString((char)c);
}

// temp就是从文件中读取的内容
in.close();

4. 文件读取示例

前面提到过,对于文件的操作主要就是输入和输出,所以我们就围绕这两个操作来做一个示例。下面一起编写一段代码,通过输入一段字符串然后保存到文件中,后续可以任意杀掉进程退出 App,再点击“读取”即可获取到前面输入的字符串内容,完成一个文件的保存和读取。

4.1 布局文件

首先我们来编写布局文件,核心内容很简单,主要有四个元素:

  1. 输入框: 接收需要保存的数据
  2. 数据文本: 展示从文件中读取的数据
  3. 保存/加载: 点击触发数据的输入和输入

布局代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:padding="30dp"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:text="文件存储"
        android:textSize="35sp" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/title"
        android:layout_centerHorizontal="true"
        android:text="Android教程"
        android:textColor="#ff7aff24"
        android:textSize="35sp" />

    <Button
        android:id="@+id/save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/textView"
        android:layout_alignParentBottom="true"
        android:text="保存" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageView"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="42dp"
        android:hint="输入要保存的内容"
        android:textColorHighlight="#ff7eff15"
        android:textColorHint="#ffff25e6" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView"
        android:layout_centerHorizontal="true"
        android:src="@mipmap/ic_launcher" />

    <Button
        android:id="@+id/load"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/save"
        android:layout_alignEnd="@+id/editText"
        android:text="加载文件" />

    <TextView
        android:id="@+id/content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/editText"
        android:layout_centerHorizontal="true"
        android:textColor="#ff5bff1f"
        android:textSize="25sp" />

</RelativeLayout>

4.2 I/O 逻辑编写

我们在 MainActivity 中给几个核心元素增加事件处理,其中两个 Button 的 onClick 事件就分别对应这文件的“输入”、“输出”操作,代码如下:


package com.emercy.myapplication;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;

public class MainActivity extends Activity {

    Button save, load;
    TextView content;
    EditText input;

    String data;
    private String file = "MC_data";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        save = findViewById(R.id.save);
        load = findViewById(R.id.load);

        input = findViewById(R.id.editText);
        content = findViewById(R.id.content);
        save.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                data = input.getText().toString();
                try {
                    FileOutputStream fOut = openFileOutput(file, MODE_WORLD_READABLE);
                    fOut.write(data.getBytes(StandardCharsets.UTF_8));
                    fOut.close();
                    Toast.makeText(getBaseContext(), "文件保存成功", Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        load.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    FileInputStream fin = openFileInput(file);
                    byte[] buf = new byte[1024];
                    int count;
                    StringBuilder temp = new StringBuilder();
                    while ((count = fin.read(buf)) > 0) {
                        temp.append(new String(buf, 0, count, StandardCharsets.UTF_8));
                    }
                    content.setText(temp.toString());
                    Toast.makeText(getBaseContext(), "文件加载成功", Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

save 的 onCilck 事件里的就是文件输出,比较简单;而 load 里面的 onClick 事件所做的事就是文件输入,这里有一段核心代码我们单独看看:

 FileInputStream fin = openFileInput(file);
                    byte[] buf = new byte[1024];
                    int count;
                    StringBuilder temp = new StringBuilder();
                    while ((count = fin.read(buf)) > 0) {
                        temp.append(new String(buf, 0, count, StandardCharsets.UTF_8));
                    }

这里我们先创建一个大数据——buf[1024],然后调用“inputStream”的read(buf)方法,此方法会尽可能的从输入流中读取数据到 buf 数组中,并返回真实读取的数据。此时判断读取的数据是否大于0,如果不大于 0 则表示文件已到末尾,就可以跳出循环结束读取。
编译之后,在文本输入框输入任意字符,之后可以杀进程、关手机等等操作,再次进入 App,点击“加载”依然可读取到之前输入的内容。效果如下:

5. 小结

本节讲述了一种 Android 数据持久化最直接的方式,我们通过openFileOutput打开一个文件输出流,然后往输出流里 write 数据,就可以在 SD 卡上创建一个文件;而后通过openFileInput打开一个文件输入流,接着从输入流里拿到文件内容就可以还原原始数据,完成一个数据的持久化操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1625361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

任务调度xxljob的使用记录

1.基本使用 a.下载代码&#xff0c;地址&#xff1a;https://gitee.com/xuxueli0323/xxl-job.git b.执行sql&#xff0c;修改配置&#xff0c;启动任务调度中心的代码 启动代码后任务调度中心访问地址&#xff1a;http://localhost:8080/xxl-job-admin&#xff08;自己机器…

html表格导出为word文档,导出的部分表格内无法填写文字

导出技术实现&#xff1a;fileSaver.jshtml-docx-js 1.npm安装 npm install --save html-docx-js npm install --save file-saver 2.页面引入 import htmlDocx from html-docx-js/dist/html-docx; import saveAs from file-saver;components: {htmlDocx,saverFile, }, 3.页…

夜神、雷电、android studio手机模拟器资源占用情况

夜神、雷电、android studio手机模拟器内存资源占用情况 由于开发电脑只有16G内存&#xff0c;出于开发需要和本身硬件资源的限制&#xff0c;对多个手机模拟器进行了机器资源占用&#xff08;主要是内存&#xff09;的简单比较。 比较的模拟器包括&#xff1a; 1. Android S…

在线HTML编辑器源码

在线HTML编辑器源码 效果图部分源码领取源码下期更新预报 效果图 部分源码 index.html <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>在线HTML编辑器</title><meta name"viewport" content"…

idea配置未运行过的springboot项目

1、File -> Settings -> Build, Execution, Deployment -> Build Tools -> Maven&#xff0c;把路径配置成自己的settion、repository 2、在pom.xml中右键&#xff0c;点击"Add as Maven Project" 3、File -> Project Structure… , 把jdk版本设置为该…

OpenCV 实现霍夫圆变换

返回:OpenCV系列文章目录&#xff08;持续更新中......&#xff09; 上一篇&#xff1a;OpenCV实现霍夫变换 下一篇:OpenCV 实现重新映射 目标 在本教程中&#xff0c;您将学习如何&#xff1a; 使用 OpenCV 函数 HoughCircles()检测图像中的圆圈。 理论 Hough 圆变换 H…

模拟从D盘查找图片文件进行预览改进版

<style>#files button {margin-right: 10px;background-color: #0b4180;color: white;}#files button:hover {background-color: #00B83F;color: #0C0C0C;}#file-list li:hover {cursor: pointer;color: red;}#showImg {width: 100%; /* 图片宽度100% */max-height: 80vh…

三种类的免费SSL证书

目前主流的三种域名证书&#xff1a;单域名证书、多域名证书、通配符泛域名证书。 这三种类型的证书根据用户域名的不同情况&#xff0c;应用场景也大不相同。 单域名证书应用场景&#xff1a; 针对于有且只有一个单独域名的单位&#xff0c;使用单域名证书是刚好能够满足需求…

python逆向基础流程(纯小白教程)

一&#xff0c;例题链接 NSSCTF | 在线CTF平台 二&#xff0c;文件特征 使用工具查看文件信息&#xff0c;发现是pyinsatller打包的exe文件&#xff0c;如果硬用ida分析成汇编或c语言根本摸清楚程序的逻辑&#xff0c;所以思路是反编译成py文件直接分析python代码 三&#xf…

Idea:阿里巴巴Java编码插件

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、Alibaba Java Coding Guidelines插件介绍 二、使用步骤 总结 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、Alibaba Java Coding …

性能测试学习一

文章目录 什么是性能测试性能项目分类性能测试流程在这里插入图片描述 场景分类基准场景 容量场景稳定性场景性能指标性能指标 分布式压测 日期&#xff1a;2024年4月19日 从今日起开始系统更新性能测试学习笔记&#xff0c;一方面督促自身的学习进度&#xff0c;另一方面提高专…

网络爬虫之HTTP原理

** URI和URL URI的全称Uniform Resource Identifier &#xff0c;即统一资源标志符。URL的全称Uniform Resource Locator 即统一资源定位符。 URL是URI的子集&#xff0c;也就是每一个URL就是URI&#xff0c;但是每一个URI不一定是URL&#xff0c;URI还有一个子类叫URN&#x…

企业微信hook接口协议,ipad协议http,发送大视频文件

发送大视频文件 参数名必选类型说明uuid是String每个实例的唯一标识&#xff0c;根据uuid操作具体企业微信send_userid是long要发送的人或群idisRoom是bool是否是群消息 请求示例 {"uuid":"1688853790xxx", //uuid 默认随机生成如果初始化传了id则用初始…

数组和指针有什么区别?

数组&#xff08;Array&#xff09;和指针&#xff08;Pointer&#xff09;是计算机编程中常见的两种数据类型&#xff0c;它们在内存中的表示和使用方式有着显著的区别。 1. 内存中的表示&#xff1a; 数组&#xff1a; 数组是一组相同类型的元素在内存中连续存储的集合。在…

企业数字化管理是什么,如何建立企业数字化管理?

前言 随着信息技术的迅猛发展和数字化浪潮的席卷&#xff0c;企业数字化管理已成为现代企业管理的重要趋势。数字化管理不仅有助于提升企业的运营效率和市场竞争力&#xff0c;还能为企业创造更多的商业价值和机遇。因此&#xff0c;深入了解和掌握企业数字化管理的内涵和建立…

【企业管理战略方案设计】经营驱动与管理控制相结合

在企业发展过程中&#xff0c;是经营为先&#xff0c;还是管理为先&#xff1f;是经营重要还是管理重要&#xff1f;不同的人可能会有不同的答案&#xff0c;也会有不同的简介。但是如何将经营与管理有机地结合在一起&#xff0c;将冲锋陷阵的前方经营与补充粮草的后方管理加以…

C#实现TFTP客户端

1、文件结构 2、TftpConfig.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace TftpTest {public class TftpConfig{}/// <summary>/// 模式/// </summary>public enum Modes{…

前端单元测试的艺术:专业化策略与Vue项目高效实践指南

单元测试是软件开发中的基石&#xff0c;尤其对于前端领域&#xff0c;它为保证代码质量、提升开发效率、强化项目稳定性提供了不可或缺的支持。本文将深入剖析单元测试的核心理念&#xff0c;揭示其在前端开发中的独特价值&#xff0c;并提炼出一套专业且高效的实践策略&#…

闲谈工作边界

在程序员的日常工作中&#xff0c;会遇到很多边界问题。如果这些边界问题不处理好&#xff0c;会面临诸多问题。切不可忽略边界问题&#xff0c;因为这些边界很有可能是日后帮助你摆脱扯皮&#xff0c;避免被甩锅&#xff0c;甚至于好心办坏事。 那么我们来谈一下如何处理边界问…

关于螺栓的注意事项和正确操作方法——SunTorque智能扭矩系统

智能扭矩系统-智能拧紧系统-扭矩自动控制系统-SunTorque 螺栓&#xff0c;作为一种常见的紧固件&#xff0c;广泛应用于各种机械设备和结构中。在日常生活和工作中&#xff0c;我们经常需要接触到螺栓&#xff0c;因此了解螺栓的一些注意事项和正确操作方法对于确保设备的安全…