[Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练
🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪
Topic
发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。

📋笔记目录
🪁文件存储
💾内部存储
📀存储数据到文件
💿从文件中读取数据
💯实战演练--保存QQ账号与密码
📖acticity_main.xml布局文件
📖 FileSaveQQ.java文件
📖MainActivity.java文件
⭐验证文件存储
🚩结尾
🪁文件存储
文件存储是Android中最基本的一种数据存储方式,其与Java中的文件存储类似,都是通过I/O流的形式把数据直接存储到文件中。
如果想要将数据存入文件中,有两种存储方式,一种是内部存储,一种是外部存储。其中内部存储是将数据以文件的形式存储到应用中,外部存储是将数据文件的形式存储到一些外部设备上,如SD卡。
今天学习的是Android 文件存储中的内部存储形式。
💾内部存储
内部存储是指将应用程序中的数据与文件的形式存储到应用中,此时存储的文件会被其所在的应用存序私有化,如果其他应用程序想要操作文应用程序中的文件则需要设置权限,当创建的应用程序被卸载时,其内部存储文件也随之被删除。
Android开发中,内部存储使用的是 Context 提供的 openFileOutput() 方法和 openFileInput() 方法,这两种方法能够返回进行读写操作的 FileoutputStream 对象和 FileInputstream 对象。
FileOutputStream fos = openFileOutput(String name,int mode);
FileInputStream fis = openFileInput(String name);
openFileOutput()方法,用打开应用程序中对应的输出流,将数据存储到指定的文件中。
openFileInput()方法用于打开应用程序对应的输入流,读取指定文件中的数据。
它们的参数"name"表示文件名,"mode"表示文件的操作模式,也就是读写文件的形式.
"mode"的取值有四种,具体如下:
MODE_PRIVATE: 该文件只能被当前程序读写;
MODE_APPEND: 该文件的内容可以追加;
MODE_WORLD_READABLE: 该文件的内容以被其他程序读;
MODE_WORLD_WRITEABLE: 该文件的内容可以被其他程序写。
值得注意的是,安卓系统有一套自己的安全模型,默认情况下,任何应用创建的文件都是私有的,其他程序无法访问,除非在文件创建时指定的操作模式为MODE_WORLD_READABLE或MODE_WORLD_WRITEABLE,如果希望文件能够被其他程序进行读写操作,则需要同时指定该文件MODE_WORLD_READABLE 和 MODE_WORLD_WRITEABLE的权限。
📀存储数据到文件
存储数据时,使用FileOutputStream对象将数据存储到文件中,实例代码如下:
String fileName = "data.txt"; //文件名称String content = "helloworld"; //保存数据FileOutputStream fos = null;try {fos = context.openFileOutput(FileName,MODE_PRIVATE);fos.write((content.getBytes()); //将数据写入文件中return true;} catch (Exception e) {e.printStackTrace();}finally {try {if (fos != null){fos.close();}} catch (IOException e) {e.printStackTrace();}
上述代码中首先定义了两个String类型的变量fileName和content,这两个变量的值”data.txt“ 与 ”helloworld“分别表示文件名与要写入文件的数据,接着创建了FileOutputStream对象,fos通过该对象的write()方法将数据"helloworld"写入"data.txt"文件。
💿从文件中读取数据
存储好数据之后,如果需要获取这些数据,则需要从文件中读取存储的数据,关于读取内部存储文件中的数据,具体方式如下所示:
String content = "";FileInputStream fis = null;try { fis = context.openFileInput("data.txt"); //获取文件输入流对象byte[] buffer = new byte[fis.available()]; //创建缓冲区,并获取文件长度fis.read(buffer); //将文件内容读取到buffer缓冲区content = new String(buffer); //转换成字符串} catch (Exception e) {e.printStackTrace();}finally {try {if (fis != null){fis.close(); //关闭输入流}} catch (IOException e) {e.printStackTrace();}}
上述代码中首先通过openFileinput()方法获取到文件输入流对象,然后通过available()方法获取文件的长度,并创建相应大小的byte数组作为缓冲区,再通过read()方法将文件内容读取到buffer缓冲区中,最后将读取到的内容转换成指定字符串。
💯实战演练--保存QQ账号与密码
效果演示

1,创建程序
创建一个名为SaveQQ的应用程序,指定报名为cn.example.saveqq。
2,导入界面图片
将保存QQ密码界面所需要的图片head.png导入到项目中的drawable文件夹中,
3,放置界面图片
在activity_main.xml布局文件中放置一个ImageView控件,用于显示用户头像,两个TextView控件,用于分别用于显示"账号: "与"密码: "文本信息,两个EditText控件分别用于输入账号和密码信息,一个Button控件用于显示登录按钮。
4,创建工具类
由于QQ账号和密码需要存放在文件中,因此,需要在程序中的cn.example.saveqq包中创建一个工具类FileSaveQQ,在该类中实现QQ账号和密码的存储与读取功能。
📖acticity_main.xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="10dp"android:background="#E6E6E6"><ImageViewandroid:layout_width="70dp"android:layout_height="70dp"android:layout_marginTop="30dp"android:layout_gravity="center_horizontal"android:src="@drawable/head"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="15dp"android:background="@android:color/white"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:text="账号:"android:textColor="#000"android:textSize="20sp" /><EditTextandroid:hint="输入的是数字"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/et_account"android:layout_marginLeft="5dp"android:background="@null"android:padding="10dp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:background="@android:color/white"android:orientation="horizontal"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/tv_password"android:padding="10dp"android:text="密码:"android:textSize="20sp"android:textColor="#000"/><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/et_password"android:layout_marginLeft="5dp"android:background="@null"android:inputType="textPassword"android:padding="10dp"/></LinearLayout><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/btn_login"android:text="登录"android:layout_marginTop="25dp"android:background="#3c8dc4"android:textColor="@android:color/white"android:textSize="20sp"/></LinearLayout>
📖 FileSaveQQ.java文件
package com.example.saveqq;import android.content.Context;import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;public class FileSaveQQ {public static boolean saveUserinfo(Context context,String account,String password){FileOutputStream fos = null;try {fos = context.openFileOutput("data.txt",Context.MODE_PRIVATE);fos.write((account + ":" +password).getBytes());return true;} catch (Exception e) {e.printStackTrace();return false;}finally {try {if (fos != null){fos.close();}} catch (IOException e) {e.printStackTrace();}}}public static Map<String,String> getUserInfo(Context context){String content = "";FileInputStream fis = null;try {fis = context.openFileInput("data.txt");byte[] buffer = new byte[fis.available()];fis.read(buffer);content = new String(buffer);Map<String,String> userMap = new HashMap<String, String>();String[] infos = content.split(":");userMap.put("account",infos[0]);userMap.put("password",infos[1]);return userMap;} catch (Exception e) {e.printStackTrace();return null;}finally {try {if (fis != null){fis.close();}} catch (IOException e) {e.printStackTrace();}}}
}
📖MainActivity.java文件
package com.example.saveqq;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import java.util.Map;public class MainActivity extends AppCompatActivity implements View.OnClickListener {private EditText et_account;private EditText et_password;private Button btn_login;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();Map<String,String> userInfo = FileSaveQQ.getUserInfo(this);if (userInfo != null){et_account.setText(userInfo.get("account"));et_password.setText(userInfo.get("password"));}}private void initView() {et_account = findViewById(R.id.et_account);et_password = findViewById(R.id.et_password);btn_login = findViewById(R.id.btn_login);btn_login.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_login:String account = et_account.getText().toString().trim();String password = et_password.getText().toString();if (TextUtils.isEmpty(account)){Toast.makeText(this,"请输入QQ号",Toast.LENGTH_SHORT).show();return;}if (TextUtils.isEmpty(password)){Toast.makeText(this,"请输入密码",Toast.LENGTH_SHORT).show();return;}Toast.makeText(this,"登录成功",Toast.LENGTH_SHORT).show();boolean isSaveSucess = FileSaveQQ.saveUserinfo(this,account,password);if (isSaveSucess){Toast.makeText(this,"保存成功",Toast.LENGTH_SHORT).show();}else {Toast.makeText(this,"保存失败",Toast.LENGTH_SHORT).show();}break;}}
}
⭐验证文件存储
为了验证程序是否操作成功,可以通Device File Explorer视图中找到data/data目录,并在该目录中找到本程序对应报名中的data.txt文件,该文件所在的目录下图所示,双击Device File Explorer视图中的data.txt,即可Android Studio编辑框中查看data,txt文件中存储的QQ账号和密码数据,此时说明存储成功。
如需使用设备的文件系统,请按以下步骤操作:
- 如需打开设备浏览器,请依次选择 View > Tool Windows > Device File Explorer,或点击工具窗口栏中的 Device File Explorer 按钮。
- 从列表中选择设备。
- 在文件浏览器窗口中与设备内容交互:
- 右键点击某个文件或目录即可创建新的文件或目录。
- 保存、上传、删除所选文件或目录,或将其同步到您的计算机。
- 双击某个文件可在 Android Studio 中将其打开。

可以找到Android Studio 模拟机上的所装载的应用程序的文件存储内容。

🚩结尾
至此,文件存储的相关知识已讲解完成,该知识所用到的核心技术是利用I/O流来进行文件读写操作,其中,Context类中提供的openFileInput()和OpenFileOutput()方法的用法,一定要掌握。

🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝
🌈写给读者:很高兴你能看到我的文章,希望我的文章可以帮助到你,祝万事顺意🏳️🌈
相关文章:
[Android Studio]Android 数据存储-文件存储学习笔记-结合保存QQ账户与密码存储到指定文件中的演练
🟧🟨🟩🟦🟪 Android Debug🟧🟨🟩🟦🟪 Topic 发布安卓学习过程中遇到问题解决过程,希望我的解决方案可以对小伙伴们有帮助。 📋笔记目…...
【openGauss实战9】深度分析分区表
📢📢📢📣📣📣 哈喽!大家好,我是【IT邦德】,江湖人称jeames007,10余年DBA及大数据工作经验 一位上进心十足的【大数据领域博主】!😜&am…...
XSS跨站脚本攻击剖析与防御:初识XSS
目录 跨站脚本介绍 1. 什么是XSS跨站脚本 2. XSS跨站脚本实例 3. XSS漏洞的危害 XSS的分类 1. 反射型XSS 2. 持久性XSS XSS构造 1. 利用< >标记注射Html /Javascript 2. 利用HTML标签属性值执行XSS 3. 空格回车Tab 4. 对标签属性值转码 5. 产生自己的事件…...
Python 高级编程之网络编程 Socket(六)
文章目录一、概述二、Python socket 模块1)Socket 类型1、创建 TCP Socket2、创建 UDP Socket2)Socket 函数1、服务端socket函数2、客户端socket函数3、公共socket函数三、单工,半双工以及全双工通信方式的区别四、单工,半双工以及…...
centos学习记录
遇到的问题及其解决办法 centos7安装图形化界面 yum groupinstall ‘X Window System’ yum groupinstall -y ‘GNOME Desktop’ 安装完成后输入init 5进入图形化界面 centos7安装vmware-tools 第一步卸载open-vm-tools 输入命令 yum remove open-vm-tools 输入命令 reboot 在…...
为什么说网络安全是风口行业?
前言 “没有网络安全就没有国家安全”。当前,网络安全已被提升到国家战略的高度,成为影响国家安全、社会稳定至关重要的因素之一。 网络安全行业特点 1、就业薪资非常高,涨薪快 2021年猎聘网发布网络安全行业就业薪资行业最高人均33.77万&…...
12-PHP使用过的函数 111-120
111、rowCount if ($stmt->execute($data)) {//true//读:select//写:insert,update,delete,成功后会返回表中受影响的记录数量//!rowCount() 返回受影响的记录数量if ($stmt->rowCount() > 0) {echo 新增成功,id . $db->lastInsertId() . <hr>;} else {//…...
【JavaWeb项目】简单搭建一个前端的博客系统
博客系统项目 本项目主要分成四个页面: 博客列表页博客详情页登录页面博客编辑页 该系统公共的CSS样式 common.css /* 放置一些各个页面都会用到的公共样式 */* {margin: 0;padding: 0;box-sizing: 0; }/* 给整个页面加上背景 */ html, body{height: 100%; }body {backgrou…...
iPerf3 -M参数详解,场景分析
本文目录iPerf3 -M参数说明几个典型测试场景中应该如何设定合适的-M参数值理想局域网模型(无丢包,无抖动)高丢包,无抖动模型高丢包,高抖动模型(网络质量比较差,IP转发路径变化频繁)总…...
java的基本语法以及注意事项
Java 基础语法一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它…...
matlab搭建IAE,ISE,ITAE性能指标
目录前言准备IAEISEITAE前言 最近在使用matlab搭建控制系统性能评价指标模型,记录一下 准备 MATLAB R2020 IAE IAE函数表达式如下所示: IAE函数模型如下所示: ISE ISE函数表达式如下所示: ISE函数模型如下所示ÿ…...
docker安装mysql
在安装Mysql之前,我们可以先查看一下我们的镜像,输入命令: docker images 能发现,镜像里面只有一个Nginx,并没有Mysql 然后我们可以像上一篇安装Nginx一样,安装Mysql镜像。 输入以下命令,安装…...
Leetcode 回溯详解
回溯法 回溯法有“通用解题法”之称,用它可以系统地搜索问题的所有解。回溯法是一个既带有系统性又带有跳跃性的搜索算法。 在包含问题的所有解的解空间树中,按照深度优先搜索(DFS))的策略,从根结点出发深度探索解空间树。当探索…...
AI_Papers:第一期
2023.02.06—2023.02.12 文摘词云 Top Papers Subjects: cs.CL 1.Multimodal Chain-of-Thought Reasoning in Language Models 标题:语言模型中的多模式思维链推理 作者:Zhuosheng Zhang, Aston Zhang, Mu Li, Hai Zhao, George Karypis, Alex Sm…...
C/C++内存管理
C/C内存管理C/C内存分布C语言中内存管理的方式:malloc/calloc/realloc/freeC内存管理方式内置类型自定义类型operator new 与operator deletenew和delete的实现原理内置类型自定义类型定位new表达式(placement-new)new/delete与malloc/free的区别C/C内存分布 我们先…...
【大数据hive】hive 函数使用详解
一、前言 在任何一种编程语言中,函数可以说是必不可少的,像mysql、oracle中,提供了很多内置函数,或者通过自定义函数的方式进行定制化使用,而hive作为一门数据分析软件,随着版本的不断更新迭代,…...
彻底搞懂分布式系统服务注册与发现原理
目录 引入服务注册与发现组件的原因 单体架构 应用与数据分离...
安卓Camera2用ImageReader获取NV21源码分析
以前如何得到Camera预览流回调 可以通过如下方法,得到一路预览回调流 Camera#setPreviewCallbackWithBuffer(Camera.PreviewCallback),可以通过如下方法,设置回调数据的格式,比如 ImageFormat.NV21 Camera.Parameters#setPreview…...
24. 两两交换链表中的节点
文章目录题目描述迭代法递归法参考文献题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例 1: 输入&a…...
linux006之帮助命令
linux帮助命令简介: linux的命令是非常多的,光靠人是记不住的,在工作中一般都会去网上查,这是有外网的情况下,如果项目中不允许访问外网,那么linux的帮助命令就可以派上用场了, linux帮助命令是…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
4. TypeScript 类型推断与类型组合
一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式,自动确定它们的类型。 这一特性减少了显式类型注解的需要,在保持类型安全的同时简化了代码。通过分析上下文和初始值,TypeSc…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
