首先创建一个csv文件,创建方式为新建一个文本文档,然后将这个文本文档重命名为test.csv 再用Excel打开,添加内容 内容如下: ?...先来添加列 data = [‘a’,’b’,’c’] df[‘字母’] = data import pandas as pd filename = '....,所以是encoding=‘gbk’ 由于我将文件放在了python的工程文件夹内,所以filename=’....再来添加行 df.loc[4]=[4,’d’] import pandas as pd filename = '....,希望对大家的学习有所帮助。
在您应用的任何地方,每当 Service 或 Activity 启动或停止时,就会触发等待 fsync() 的调用。...一样,不能定义 schema 或保证以正确的类型访问键值。...虽然 Proto DataStore 要求您学习一种新的序列化机制,但考虑到 Proto DataStore 所带来的强类型 schema 的优势,我们认为这样的代价是值得的。...Proto DataStore,您还需要实现 Serializer 接口来告诉 DataStore 如何读取和写入您的数据类型。...,用来定义如何将 SharedPreferences 所使用的键值对迁移到您所定义的 DataStore schema。
2.1 Memory Mapping 内存映射 Memory Mapping 简称 MMap 是一种将磁盘上文件的一部分或整个文件映射到应用程序地址空间的一系列地址机制,从而应用程序可以用访问内存的方式访问磁盘文件...由此可见,MMap 的优势很明显了,因为进行了内存映射,操作内存相当于操作文件,无需开启新的线程,相较于 I/O 对文件的读写操作只需要从磁盘到用户主存的一次数据拷贝过程,减少了数据的拷贝次数,提高了文件的操作效率...protobuf 在更新文件时,虽然也不方便局部更新,但是可以做增量更新,即不管之前是否有相同的 key,一旦有新的数据便添加到文件最后,待最终文件读取时,后面新的数据会覆盖之前老旧的数据;...当添加新的数据时文件大小不够了,需要全量更新,此时需要将 Map 中数据按照 MMKV 方式序列化,滤重后保存需要的字节数,根据获取的字节数与文件大小进行比较;若保存后的文件大小可以添加新的数据时直接添加在最后面...,若保存后的文件大小还是不足以添加新的数据时,此时需要对 protobuf * 2 扩容; protobuf 功能简单,作为二进制存储,可读性较差;同时无法表示复杂的概念,通用性相较于 xml 较差;
Memory Mapping 简称 MMap 是一种将磁盘上文件的一部分或整个文件映射到应用程序地址空间的一系列地址机制,从而应用程序可以用访问内存的方式访问磁盘文件; [6o252k3np7...,因为进行了内存映射,操作内存相当于操作文件,无需开启新的线程,相较于 I/O 对文件的读写操作只需要从磁盘到用户主存的一次数据拷贝过程,减少了数据的拷贝次数,提高了文件的操作效率;同时 MMap 只需要提供一段内存...,只需要关注往内存文件中读写操作即可,在操作系统内存不足或进程退出时自动写入文件中; 当然,MMap 也有自身的劣势,因为 MMap 需要提供一度长度的内存块,其映射区的长度默认是一页,即...,虽然也不方便局部更新,但是可以做增量更新,即不管之前是否有相同的 key,一旦有新的数据便添加到文件最后,待最终文件读取时,后面新的数据会覆盖之前老旧的数据; 当添加新的数据时文件大小不够了...,需要全量更新,此时需要将 Map 中数据按照 MMKV 方式序列化,滤重后保存需要的字节数,根据获取的字节数与文件大小进行比较;若保存后的文件大小可以添加新的数据时直接添加在最后面,若保存后的文件大小还是不足以添加新的数据时
() 都会创建一个新的 EditorImpl 对象,当修改或者添加数据时会将其添加到 EditorImpl 的 mModifiled 容器中,通过 commit 或 apply 提交后会比较 mModifiled...进程再次启动后如果发现该 SharedPreferences 存在 Backup 文件,就将 Backup 文件重名为源文件,原本未完成写入的文件就直接丢弃,这样最多也就是未完成写入的数据丢失,它能保证最后一次落盘...也正式这个 BackUp 机制,导致多进程可能会丢失新写入的数据。但也不是只有多进程场景才会发生数据丢失的情况。...9.SharedPreferences的优化可以引申出来mmkv的实现原理 MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,Linux...MMAP优势 1.MMAP对文件的读写操作只需要从磁盘到用户主存的一次数据拷贝过程 2.MMAP使用逻辑内存对磁盘文件进行映射,操作内存就相当于操作文件,不需要开启线程,操作MMAP的速度和操作内存的速度一样快
在您应用的任何地方,每当 Service 或 Activity 启动或停止时,就会触发等待 fsync() 的调用。...一样,不能定义 schema 或保证以正确的类型访问键值。...虽然 Proto DataStore 要求您学习一种新的序列化机制,但考虑到 Proto DataStore 所带来的强类型 schema 的优势,我们认为这样的代价是值得的。...DataStore 是小型、简单数据集的理想选择,它并不支持局部更新与参照完整性。 使用 DataStore 首先添加 DataStore 依赖项。...,用来定义如何将 SharedPreferences 所使用的键值对迁移到您所定义的 DataStore schema。
SharedPreferences 使用不当可能引发的“严重后果”以及该如何正确的使用 SharedPreferences。...) { if (mSharedPrefsPaths == null) { //mSharedPrefsPaths维护文件名name和文件File 的映射关系...,这里主要维护了 SharedPreferences 文件名 name 和文件 File 的映射关系,既根据文件名 name 得到文件 File,每个 Activity 都会包含一个 ContextImpl...其实不难分析出 commitToMemory 方法主要工作是:前面我们一系列的 putXxx() 或 remove() 操作都会添加到 mModified 临时容器中,mModified 保留着我们当前的改变...每当我们 edit 都会创建一个新的 EditorImpl 对象,当修改或者添加数据时会将其添加到 EditorImpl 的 mModifiled 容器中,通过 commit 或 apply 提交后会比较
不对存储内容做任何的格式化处理,所有数据都是原封不动地保存到文件中。因此,这种方式比较适合存储一些文本数据或二进制数据。...,而MODE_APPEND则表示如果该文件已经存在,则将新内容追加到原文件内容的后面。...SharedPreferences.Editor对象editor 向上一步获取的SharedPreferences.Editor对象中添加数据,比如添加一个boolean型数据就使用editor.putBoolean...,第二个一般直接传入null即可,第三个参数是一个ContentValues对象,它提供了一系列的put()方法的重载,用于向ContentValues对象中添加数据,只需将表中的每个列名以及相应的待添加的数据传入即可...第一个参数就是表名,第二个是要更新的数据组装成的ContentValues对象,第三个和第四个参数用于约束更新某一行或某几行的数据,不指定的话是默认更新所有行。
在这篇文章中,我将向大家分享Flutter 本地存储的一些实用知识和技巧。...在你学习Flutter 本地存储过程中遇到无法解决的问题或疑问,都可以在课程问答区进行提问,课程老师会对你进行辅导和帮助; 目录 shared_preferences 是什么?...如何使用shared_preferences ? shared_preferences有那些常用的API?...上它是基于SharedPreferences的; 在iOS上它是基于NSUserDefaults的; 如何使用shared_preferences?...首先在pubspec.yaml文件中添加: dependencies: shared_preferences: ^0.5.1+ 记得运行安装哦:flutter packages get 在需要用到的文件中导入
通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据, 由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。...4.空间增长 使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。...可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。 2.多进程性能 ?...2.mmap 通过mmap来访问文件,mmap()将文件直接映射到用户空间,文件在mmap的时候,内存并未真正分配, 只有在第一次读取/写入的时候才会触发,这个时候,会引发缺页中断,在处理缺页中断的时候...然后调用ByteBuffer的put方法添加数据。
一个官方发布的、更(gèng)新的库,性能竟然比不过比它早两年发布的、第三方的库。而且我们能看到,更离谱的是,它甚至还比不过 SharedPreferences 。...它可以让系统为你指定的文件开辟一块专用的内存,这块内存和文件之间是自动映射、自动同步的关系,你对文件的改动会自动写到这块内存里,对这块内存的改动也会自动写到文件里。...而且这个内存映射还有一点很方便的是,虽然这块映射的内存不是实时向对应的文件写入新数据,但是它在程序崩溃的时候,并不会随着进程一起被销毁掉,而是会继续有条不紊地把它里面还没同步完的内容同步到它所映射的文件里面去...不管是用户打开新的聊天页面,还是滑动聊天记录来查看聊天历史,用内存映射的方式都可以既实时写入所有即将被渲染的文字,又不会造成界面的卡顿。...对于这种文件损坏,SharedPreferences 和 DataStore 的应对方式是在每次写入新数据之前都对现有文件做一次自动备份,这样在发生了意外出现了文件损坏之后,它们就会把备份的数据恢复过来
缓存容量,就是缓存的大小每一种缓存,总会有一个最大的容量,到达这个限度以后,那么就须要进行缓存清理了框架。这个时候就需要删除一些旧的缓存并添加新的缓存。...当缓存满了之后,再想其添加缓存,这个时候就需要删除一些旧的缓存并添加新的缓存。这个跟线程池满了以后的线程处理策略相似!...DataStore:旨在替代原有的 SharedPreferences,支持SharedPreferences数据的迁移Room/Realm/GreenDao:支持大型或复杂数据集图片其他开源缓存库ACache...它有一些弊端如下所示对文件IO读取,因此在IO上的瓶颈是个大问题,因为在每次进行get和commit时都要将数据从内存写入到文件中,或从文件中读取。...它设计初衷是轻量级,建议当存储文件中key-value数据超过30个,如果超过30个(这个只是一个假设),则开辟一个新的文件进行存储。
在SharedPreferences中存储数据一共有四个步骤:首先,获取一个SharedPreferences对象,然后再获取一个Editor对象;通过Editor就可以向SharedPreferences...values中存放要写入数据库的信息,然后用SQLiteDatabase的insert函数向表中添加数据。...insert向数据库中添加一条数据,将待添加的数据保存在 values 参数中。...添加完成后,返回一个用来表示这条新记录的 URI。...File对象,如果该文件夹不存在则用指定名称创建一个新的文件夹。
在Kotlin中,扩展函数是一种非常有用的功能,可以让我们向现有的类添加新的功能,而无需修改类的源代码。在本文中,我们将探讨Kotlin扩展函数的原理和运用,以及如何在Android开发中使用它们。...扩展函数是Kotlin中的一种特殊函数,它允许我们向一个类添加新的函数,而无需继承或修改这个类的源代码。扩展函数的语法非常简单,只需要在函数名前面加上类名,并用点号隔开即可。...扩展函数的优点 使用扩展函数有以下几个优点: 无需修改类的源代码:扩展函数可以让我们向现有的类添加新的功能,而无需修改类的源代码。这样可以避免意外修改类的行为,降低了代码的风险。...代码可读性更好:使用扩展函数可以让我们在代码中直接调用新的功能,而无需创建新的实例或引入新的类。这样可以使代码更加简洁易懂。...,可以让我们向现有的类添加新的功能,而无需修改类的源代码。
简化SharedPreferences的用法 回顾SharedPreferences的用法,向SharedPreferences中存储数据的过程: 1.调用SharedPreferences的edit(...)方法获取SharedPreferences.Editor对象: 2.向SharedPreferences.Editor对象中添加数据 3.调用apple()方法将添加的数据提交,完成数据存储。...文件: fun SharedPreferences.open(block: SharedPreferences.Editor.() -> Unit) { val editor = edit()...editor.block() editor.apply() } 通过拓展函数的方式向SharedPreferences类中添加了一个open函数,并且接收一个函数类型的参数,因此open...open函数接受的是一个SharedPreferences.Editor类型的参数因此需要调用editor.block()对函数类型参数进行调用,就可以在函数类型参数的具体实现中添加数据了。
您添加的每个 Preference 都有一个相应的键值对,可供系统用来将设置保存在应用设置的默认SharedPreferences 文件中。...当用户更改设置时,系统会为您更新 SharedPreferences 文件中的相应值。您只应在需要读取值以根据用户设置确定应用的行为时,才与关联的 SharedPreferences 文件直接交互。...决定要使用的方法以及如何拆分设置时,应遵循 Android 设计的设置指南中的准则。...,因此在用户首次打开应用时,您有必要使用每个 Preference 的默认值初始化相关的SharedPreferences 文件。...在 PreferenceActivity 中添加必要的首选项来控制应用的数据使用习惯后,您应立即在清单文件中为 ACTION_MANAGE_NETWORK_USAGE 添加 Intent 过滤器。
在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。...考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件。...MMKV 原理 内存准备 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。...空间增长 使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。...单进程性能 可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。 ?
有两种方式可以获得SharedPreferences对象 1、getSharedPreferences(): 如果需要多个使用名称来区分的共享文件,则可以使用该方法,其第一个参数就是共享文件的名称。...向SharedPreferences类中增加值的方法如下 1、调用SharedPreferences类的edit()方法获得SharedPreferences对象 2、调用诸如putString(),putInt...()等方法增加相应类型的值 3、使用commit()方法提交新的值 从SharedPreferences类中读取值时,主要使用该类中定义的getXXX()方法。...SharedPreferences类存储的数据放在shared_prefs文件夹中 ?...data/data/包名 找到你的包名 里面有个shared_prefs文件,保存的文件data.xml就是 SharedPreferences类类保存的数据 该数据是以Map键值对的形式存放在xml
显然这就要看一下SharedPreferences的实现类具体是如何进行操作的了,从他的构造函数看起,慢慢进入深度调用。...总结 是什么限制了SharedPreferences的处理速度? 这个问题在上面的源码分析中其实已经有所提及了,那就是文件读写,所以如何加快文件的读写速度是一个至关重要的突破点。...当然向速度妥协的一个方案,想来你也已经看到了,那就是异步提交,通过子线程的在用户无感知的情况下把数据写到文件中。 为什么多线程安全,而多进程不安全的操作?...一句话讲来就是,新的或更改过的就最后新增后面插入。 而新旧数据累加势必会造成文件的庞大,那这方面MMKV给出的解决方案又是怎么样的呢?...总结 从源码分析完之后,和SharedPreferences相比,重新整理后可以总结为以下几点的突破: mmap的使用: 内存映射的技术的使用,减少了 SharedPreferences 的拷贝和提交的时间消耗
在会话列表、会话界面等有大量 cell 的地方,希望新加的计时器不会影响滑动性能;另外这些计数器还要永久存储下来——因为闪退随时可能发生。...考虑到这个防 crash 方案最主要的诉求还是实时写入,而 mmap 内存映射文件刚好满足这种需求,我们尝试通过它来实现一套 key-value 组件。...再来了解下有关MMKV 原理: 内存准备 通过 mmap 内存映射文件,提供一段可供随时写入的内存块,App 只管往里面写数据,由操作系统负责将内存回写到文件,不必担心 crash 导致数据丢失。...空间增长 使用 append 实现增量更新带来了一个新的问题,就是不断 append 的话,文件大小会增长得不可控。我们需要在性能和空间上做个折中。...可见,MMKV 在写入性能上远远超越 SharedPreferences & SQLite,在读取性能上也有相近或超越的表现。
领取专属 10元无门槛券
手把手带您无忧上云