如何读写私有文件-Android内部存储实例

教程大全 2026-02-09 03:24:12 浏览

android内部存储实例详解

在Android应用开发中,内部存储是一种常见的数据存储方式,它允许应用将私有数据保存在设备内部存储空间中,这些数据仅对应用自身可见,其他应用无法直接访问,除非用户通过设备文件管理器手动授权,本文将通过实例详细介绍Android内部存储的实现方法、使用场景及注意事项。

内部存储的基本概念

Android内部存储是指设备自带的存储空间,每个应用在内部存储中都有一个专属的私有目录,路径为 /data/data/<包名>/ ,应用在此目录下创建的文件会被系统自动管理,当应用卸载时,这些文件也会被一同删除,内部存储适用于存储敏感数据、临时文件或应用配置信息,具有高安全性和易管理的特点。

内部存储的核心API

Android提供了多种API用于操作内部存储,主要包括以下方法:

内部存储的实例代码

以下是一个完整的内部存储读写实例,演示如何保存和读取用户数据:

写入数据到内部存储

// 写入数据public void saveInternalStorage(Context context, String>从内部存储读取数据
// 读取数据public String readInternalStorage(Context context) {StringBuilder stringBuilder = new StringBuilder();try {// 获取FileInputStream对象FileInputStream fis = context.OpenFileInput("user_data.txt");BufferedReader reader = new BufferedReader(new InputStreamReader(fis));String line;while ((line = reader.readLine()) != null) {stringBuilder.Append(line);}reader.close();fis.close();} catch (IOException e) {e.printStackTrace();}return stringBuilder.toString();}

内部存储的文件操作模式

在调用openFileOutput()时,可以通过不同的模式控制文件的写入方式,常见模式如下表所示:

模式常量描述
MODE_PRIVATE默认模式,仅当前应用可访问,文件存在时会覆盖
MODE_APPEND追加模式,若文件存在则追加内容,否则创建新文件
MODE_world_READABLE已弃用,允许其他应用读取文件(不推荐)
MODE_WORLD_WRITEABLE已弃用,允许其他应用写入文件(不推荐)

内部存储的适用场景

内部存储适用于以下场景:

    注意事项

      内部存储是Android应用开发中不可或缺的数据存储方式,其安全性和便捷性使其成为处理私有数据的理想选择,通过合理使用提供的API,开发者可以轻松实现文件的读写操作,但在实际开发中,需注意存储空间的合理分配和异常处理,以确保应用的稳定性和用户体验。

      通过上述实例和讲解,相信开发者已能熟练掌握Android内部存储的使用方法,并将其应用到实际项目中。


      虚函数的作用是什么?有哪些用处?何处体现多态?

      虚函数联系到多态,多态联系到继承。所以本文中都是在继承层次上做文章。没了继承,什么都没得谈。下面是对C++的虚函数这玩意儿的理解。一, 什么是虚函数(如果不知道虚函数为何物,但有急切的想知道,那你就应该从这里开始)简单地说,那些被virtual关键字修饰的成员函数,就是虚函数。虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离;用形象的语言来解释就是实现以共同的方法,但因个体差异而采用不同的策略。下面来看一段简单的代码class A{public:void print(){ cout<<”This is A”< print();p2->print();}运行一下看看结果,哟呵,蓦然回首,结果却是两个This is A。问题来了,p2明明指向的是class B的对象但却是调用的class A的print()函数,这不是我们所期望的结果,那么解决这个问题就需要用到虚函数class A{public:virtual void print(){ cout<<”This is A”< Android应用私有文件存储实例代码 定义两个类=" print(){="cout<<”this=" public:="void=" 现在成了虚函数了="};=" 现在来消化一下,我作个简单的总结,指向基类的指针在操作它的多态类对象时,会根据不同的类对象,调用其相应的函数,这个函数就是虚函数。="二,=" 由于这两个类中有虚函数存在,所以编译器就会为他们两个分别插入一段你不知道的数据,并为他们分别创建一个表。那段数据叫做vptr指针,指向那个表。那个表叫做vtbl,每个类都有自己的vtbl,vtbl的作用就是保存自己类中虚函数的地址,我们可以把vtbl形象地看成一个数组,这个数组的每个元素存放的就是虚函数的地址,请看图="通过上图,可以看到这两个vtbl分别为class="www_kuidc_com 虚函数是如何做到的(如果你没有看过《inside="the=" 虚函数示例代码="virtual=" 这里需要在前面加上关键字virtual吗?="毫无疑问,class="www_kuidc_com > fun();毫无疑问,调用了A::fun(),但是A::fun()是如何被调用的呢?它像普通函数那样直接跳转到函数的代码处吗?No,其实是这样的,首先是取出vptr的值,这个值就是vtbl的地址,再根据这个值来到vtbl这里,由于调用的函数A::fun()是第一个虚函数,所以取出vtbl第一个slot里的值,这个值就是A::fun()的地址了,最后调用这个函数。现在我们可以看出来了,只要vptr不同,指向的vtbl就不同,而不同的vtbl里装着对应类的虚函数地址,所以这样虚函数就可以完成它的任务。而对于class A和class B来说,他们的vptr指针存放在何处呢?其实这个指针就放在他们各自的实例对象里。由于class A和class B都没有数据成员,所以他们的实例对象里就只有一个vptr指针。通过上面的分析,现在我们来实作一段代码,来描述这个带有虚函数的类的简单模型。#include using namespace std;//将上面“虚函数示例代码”添加在这里int main(){void (*fun)(A*);A *p=new B;long lVptrAddr;memcpy(&lVptrAddr,p,4);memcpy(&fun,reinterpret_cast (lVptrAddr),4);fun(p);delete p;system(pause);}用VC或Dev-C++编译运行一下,看看结果是不是输出3,如果不是,那么太阳明天肯定是从西边出来。现在一步一步开始分析void (*fun)(A*); 这段定义了一个函数指针名字叫做fun,而且有一个A*类型的参数,这个函数指针待会儿用来保存从vtbl里取出的函数地址A* p=new B; new B是向内存(内存分5个区:全局名字空间,自由存储区,寄存器,代码空间,栈)自由存储区申请一个内存单元的地址然后隐式地保存在一个指针中.然后把这个地址附值给A类型的指针 lVptrAddr; 这个long类型的变量待会儿用来保存vptr的值memcpy(&lVptrAddr,p,4); 前面说了,他们的实例对象里只有vptr指针,所以我们就放心大胆地把p所指的4bytes内存里的东西复制到lVptrAddr中,所以复制出来的4bytes内容就是vptr的值,即vtbl的地址现在有了vtbl的地址了,那么我们现在就取出vtbl第一个slot里的内容memcpy(&fun,reinterpret_cast (lVptrAddr),4); 取出vtbl第一个slot里的内容,并存放在函数指针fun里。需要注意的是lVptrAddr里面是vtbl的地址,但lVptrAddr不是指针,所以我们要把它先转变成指针类型fun(p); 这里就调用了刚才取出的函数地址里的函数,也就是调用了B::fun()这个函数,也许你发现了为什么会有参数p,其实类成员函数调用时,会有个this指针,这个p就是那个this指针,只是在一般的调用中编译器自动帮你处理了而已,而在这里则需要自己处理。delete p;和system(pause); 这个我不太了解,算了,不解释这个了如果调用B::fun2()怎么办?那就取出vtbl的第二个slot里的值就行了memcpy(&fun,reinterpret_cast (lVptrAddr+4),4); 为什么是加4呢?因为一个指针的长度是4bytes,所以加4。或者memcpy(&fun,reinterpret_cast (lVptrAddr)+1,4); 这更符合数组的用法,因为lVptrAddr被转成了long*型别,所以+1就是往后移sizeof(long)的长度三, 以一段代码开始#include using namespace std;class A{ //虚函数示例代码2public:virtual void fun(){ cout< *fun)();fun = &A::fun2;(p->*fun)();delete p;system(pause);}你能估算出输出结果吗?如果你估算出的结果是A::fun和A::fun2,呵呵,恭喜恭喜,你中圈套了。其实真正的结果是B::fun和B::fun2,如果你想不通就接着往下看。给个提示,&A::fun和&A::fun2是真正获得了虚函数的地址吗?首先我们回到第二部分,通过段实作代码,得到一个“通用”的获得虚函数地址的方法#include using namespace std;//将上面“虚函数示例代码2”添加在这里void CallVirtualFun(void* pThis,int index=0){void (*funptr)(void*);long lVptrAddr;memcpy(&lVptrAddr,pThis,4);memcpy(&funptr,reinterpret_cast (lVptrAddr)+index,4);funptr(pThis); //调用}int main(){A* p=new B;CallVirtualFun(p); //调用虚函数p->fun()CallVirtualFun(p,1);//调用虚函数p->fun2()system(pause);}现在我们拥有一个“通用”的CallVirtualFun方法。 这个通用方法和第三部分开始处的代码有何联系呢?联系很大。 由于A::fun()和A::fun2()是虚函数,所以&A::fun和&A::fun2获得的不是函数的地址,而是一段间接获得虚函数地址的一段代码的地址,我们形象地把这段代码看作那段CallVirtualFun。 编译器在编译时,会提供类似于CallVirtualFun这样的代码,当你调用虚函数时,其实就是先调用的那段类似CallVirtualFun的代码,通过这段代码,获得虚函数地址后,最后调用虚函数,这样就真正保证了多态性。 同时大家都说虚函数的效率低,其原因就是,在调用虚函数之前,还调用了获得虚函数地址的代码。 最后的说明:本文的代码可以用VC6和Dev-C++4.9.8.0通过编译,且运行无问题。 其他的编译器小弟不敢保证。 其中,里面的类比方法只能看成模型,因为不同的编译器的低层实现是不同的。 例如this指针,Dev-C++的gcc就是通过压栈,当作参数传递,而VC的编译器则通过取出地址保存在ecx中。 所以这些类比方法不能当作具体实现

      GOOGLE是中国搜索引擎吗?

      Google公司(Google Inc.,NASDAQ:GOOG),是一家美国的上市公司(公有股份公司),于1998年9月7日以私有股份公司的型式创立,以设计并管理一个互联网搜索引擎;Google公司总部位于加利福尼亚山景城,在全球各地都设有销售和工程办事处。 Google网站于1999年下半年启动;2004年8月19日,Google公司的股票在纳斯达克(Nasdaq)上市,成为公有股份公司。 Google公司的总部称作“Googleplex”,位于美国加州圣克拉拉县的芒廷维尤。 在共创办人拉里_佩奇退下后,Novell公司的前任行政总裁,埃里克•施密特(Eric E. Schmidt)博士,成为了Google公司的行政总裁。

      《微机原理与接口技术》的体系结构,研究对象,研究方法,研究内容的文章。

      《现代微机原理与接口技术》课程大纲 课程编号: 课程名称: 现代微机原理与接口技术 英文名称: Interface Technology of Computer 预修课程:《汇编语言》、《微机原理》 学 时:48(理论) 学 分: 3 考核方式:考查 课程性质 专业必修课 一、 课程任务和目的 《现代微机原理与接口技术》是计算机专业的必修课。 本课程帮助学生掌握微型计算机的硬件组成及使用;学会运用指令系统和汇编语言进行程序设计;熟悉各种类型的接口及其应用,树立起微型计算机体系结构的基本概念,为后续计算机课程的学习和应用打好基础。 本课程要求学生掌握的主要内容是: 存储系统:存储器的分类(原理、存取方式)、半导体存储器工作原理、存储器的扩展、校验码、虚拟存储系统、Cache系统、地址映像、存储系统的组织。 中央处理器:CPU组成、主机与外设间的数据传送方式、同步和异步的概念、时序划分、组合及微程序控制方式的微操作命令产生部件的工作原理 输入/出设备:掌握I/O设备的分类,键盘、显示器、打印机的工作原理 输入/出系统:掌握总线的功能及分类、接口的功能及分类、直接程序传送方式接口的工作原理、程序中断方式接口的工作原理、DMA接口的工作原理 通过该课程的学习,使学生掌握计算机内部的数据信息和控制信息的传送及控制原理,并树立起整机的概念。 二、 与各课程的联系 1、与《汇编语言》的关系 《汇编语言》是本课程的先行课。 本课在介绍指令系统及CPU工作原理时,需要以具体的指令作为实例进行分析,所以,《汇编语言》是本课程的先行课。 2、与《微机原理》的关系 《微机原理》是本课程的前期课程。 《微机原理及接口技术》是基于《微机原理》介绍各种接口的工作原理。 三、 课程内容与学时分配(48学时) 第一章、微机结构的发展和特点(2学时) 第一节 微处理器发展概述 第二节 微机的硬件结构 第二章 输入输出与接口技术(4学时) 第一节 接口概述 第二节 数据传输控制方式 第三节 编址与访问 第四节 接口分析与设计方法 第三章 DMA技术 (4学时) 第一节 DMA概述 第二节 DMA控制器 第三节 8237A的编程及其应用 第四章、中断技术 (6学时) 第一节 中断基本概念 第二节 8086中断结构 第三节 微机系统的中断处理过程 第四节 可编程中断控制器8259A及其应用 第五章、定时与计数技术(6学时) 第一节 6.1概述 第二节 Intel8253 第三节 8253的编程 第四节 8253的工作方式 第五节 8254的应用 第六章、并行接口(8学时) 第一节 并行接口概述 第二节 可编程并行接口芯片82C55 第三节 82C55的编程及应用 第四节 并行接口标准 第七章、串行接口(10学时) 第一节 串行通信的基本概念 第二节 异步串行通信协议 第三节 串行接口RS-232C标准 第四节 异步通信适配器 第五节 WIN32串口编程 第八章、人机交互设备及接口 (8学时) 第一节 概述 第二节 键盘与鼠标 第三节 视频显示接口 第四节 其他外设简介 第九章、D/A及A/D转换器(6学时) 第一节、概述 第二节、典型D/A转换器芯片 第三节、典型A/D转换器芯片 第四节、DAC及ADC应用实例 四、 学时分配 本课程共计64学时,其中讲授学时计54学时(其中含机动2学时),实验学时计10学时。 整个课程的讲授和实验学时建议分配如下: 序号 内 容 讲授学时 (一) 第一章 微机结构的发展和特点 2 (二) 第二章 输入输出与接口技术 4 (三) 第三章 DMA技术 4 (四) 第四章 中断技术 6 (五) 第五章 定时与计数技术 6 (六) 第六章、并行接口 8 (七) 第七章、串行接口 10 (八) 第八章、人机交互设备及接口 8 (九) 第九章、D/A及A/D转换器 6 综合 机动 2 合 计 48学时 五、 实践(课程设计) 结合本课程所讲授的内容,完成7次实验,其中一次综合性实验。 六、考核方式: 考查 笔试占50%,实验占40%,作业占5%,考勤占5%。 七、参考教材 (1)现代计算机接口接口技术(第二版) 洪志全 洪学海 主编 电子工业出版社 (2) 微型计算机原理与接口技术 谭浩强 主编 中国铁道出版社 (3)80X86IBM PC及兼容计算机(卷I和卷II)汇编语言,设计与接口技术(第3版) 清华大学出版社

      本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

      发表评论

      热门推荐