【Android】数据存储

本章介绍Android五种主要存储方式的用法,包括共享参数SharedPreferences、数据库SQLite、SD卡文件、App的全局内存,另外介绍重要组件之一的应用Application的基本概念与常见用法,以及四大组件之一的内容提供器ContentProvider的基本概念与常见用法。

共享参数SharedPreferences

本节介绍Android的键值对存储方式——共享参数SharedPreferences的使用方法,包括如何保存数据与读取数据,通过共享参数结合“登录App”项目实现记住密码功能。

共享参数的基本用法

SharedPreferences是Android的一个轻量级存储工具,采用的存储结构是Key-Value的键值对方式,类似于Java的Properties类,二者都是把Key-Value的键值对保存在配置文件中。不同的是Properties的文件内容是Key=Value这样的形式,而SharedPreferences的存储介质是符合XML规范的配置文件。保存SharedPreferences键值对信息的文件路径是/data/data/应用包名/shared_prefs/文件名.xml。下面是一个共享参数的XML文件示例:
在这里插入图片描述

基于XML格式的特点,SharedPreferences主要适用于如下场合:
(1)简单且孤立的数据。若是复杂且相互间有关的数据,则要保存在数据库中。
(2)文本形式的数据。若是二进制数据,则要保存在文件中。
(3)需要持久化存储的数据。在App退出后再次启动时,之前保存的数据仍然有效。
实际开发中,共享参数经常存储的数据有App的个性化配置信息、用户使用App的行为信息、临时需要保存的片段信息等。
SharedPreferences对数据的存储和读取操作类似于Map,也有put函数用于存储数据、get函数用于读取数据。在使用共享参数之前,要先调用getSharedPreferences函数声明文件名与操作模式,示例代码如下:

 // 从share.xml中获取共享参数对象SharedPreferences shared = getSharedPreferences("share", MODE_PRIVATE);

getSharedPreferences方法的第一个参数是文件名,上面的share表示当前使用的共享参数文件名是share.xml;第二个参数是操作模式,一般都填MODE_PRIVATE,表示私有模式。
共享参数存储数据要借助于Editor类,示例代码如下:

 SharedPreferences.Editor editor = shared.edit();  // 获得编辑器的对象editor.putString("name", "Mr Lee");  // 添加一个名叫name的字符串参数editor.putInt("age", 30);  // 添加一个名叫age的整型参数editor.putBoolean("married", true);  // 添加一个名叫married的布尔型参数editor.putFloat("weight", 100f);  // 添加一个名叫weight的浮点数参数editor.commit();  // 提交编辑器中的修改

共享参数读取数据相对简单,直接使用对象即可完成数据读取方法的调用,注意get方法的第二个参数表示默认值,示例代码如下:

 String name = shared.getString("name", "");  // 从共享参数中获得名叫name的字符串int age = shared.getInt("age", 0);  // 从共享参数中获得名叫age的整型数boolean married = shared.getBoolean("married", false);  // 从共享参数中获得名叫married的布尔数float weight = shared.getFloat("weight", 0);  // 从共享参数中获得名叫weight的浮点数
数据库SQLite

本节介绍Android的数据库存储方式—— SQLite的使用方法,包括如何建表和删表、变更表结构以及对表数据进行增加、删除、修改、查询等操作,然后通过SQLite结合“登录App”项目改进记住密码功能。
SQLite是一个小巧的嵌入式数据库,使用方便、开发简单,手机上最早由iOS运用,后来Android也采用了SQLite。SQLite的多数SQL语法与Oracle一样,下面只列出不同的地方:
(1)建表时为避免重复操作,应加上IF NOT EXISTS关键词,例如CREATE TABLE IF NOT EXISTS table_name。
(2)删表时为避免重复操作,应加上IF EXISTS关键词,例如DROP TABLE IF EXISTS table_name。
(3)添加新列时使用ALTER TABLE table_name ADD COLUMN …,注意比Oracle多了一个COLUMN关键字。
(4)在SQLite中,ALTER语句每次只能添加一列,如果要添加多列,就只能分多次添加。
(5)SQLite支持整型INTEGER、字符串VARCHAR、浮点数FLOAT,但不支持布尔类型。布尔类型数要使用整型保存,如果直接保存布尔数据,在入库时SQLite就会自动将其转为0或1,0表示false,1表示true。
(6)SQLite建表时需要一个唯一标识字段,字段名为_id。每建一张新表都要例行公事加上该字段定义,具体属性定义为_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL。
(7)条件语句等号后面的字符串值要用单引号括起来,如果没用使用单引号括起来,在运行时就会报错。

SQLiteDatabase是SQLite的数据库管理类,开发者可以在活动页面代码或任何能取到Context的地方获取数据库实例,参考代码如下:

 // 创建名叫test.db的数据库。数据库如果不存在就创建它,如果存在就打开它SQLiteDatabase db = openOrCreateDatabase(getFilesDir() + "/test.db", Context.MODE_PRIVATE, null);// 删除名叫test.db数据库// deleteDatabase(getFilesDir() + "/test.db");

SQLiteDatabase提供了若干操作数据表的API,常用的方法有3类,列举如下:
1. 管理类,用于数据库层面的操作。

  • openDatabase:打开指定路径的数据库。
  • isOpen:判断数据库是否已打开。
  • close:关闭数据库。
  • getVersion:获取数据库的版本号。
  • setVersion:设置数据库的版本号。

2. 事务类,用于事务层面的操作。

  • beginTransaction:开始事务。
  • setTransactionSuccessful:设置事务的成功标志。
  • endTransaction:结束事务。执行本方法时,系统会判断是否已执行setTransactionSuccessful,如果之前已设置就提交,如果没有设置就回滚。

3. 数据处理类,用于数据表层面的操作。

  • execSQL:执行拼接好的SQL控制语句。一般用于建表、删表、变更表结构。
  • delete:删除符合条件的记录。
  • update:更新符合条件的记录。
  • insert:插入一条记录。
  • query:执行查询操作,返回结果集的游标。
  • rawQuery:执行拼接好的SQL查询语句,返回结果集的游标。
数据库帮助器SQLiteOpenHelper

SQLiteDatabase存在局限性,例如必须小心、不能重复地打开数据库,处理数据库的升级很不方便。Android提供了一个辅助工具—— SQLiteOpenHelper,用于指导开发者进行SQLite的合理使用。
SQLiteOpenHelper的具体使用步骤如下:
步骤01 新建一个继承自SQLiteOpenHelper的数据库操作类,提示重写onCreate和onUpgrade两个方法。其中,onCreate方法只在第一次打开数据库时执行,在此可进行表结构创建的操作;onUpgrade方法在数据库版本升高时执行,因此可以在onUpgrade函数内部根据新旧版本号进行表结构变更处理。
步骤02 封装保证数据库安全的必要方法,包括获取单例对象、打开数据库连接、关闭数据库连接。

  • 获取单例对象:确保App运行时数据库只被打开一次,避免重复打开引起错误。
  • 打开数据库连接:SQLite有锁机制,即读锁和写锁的处理;故而数据库连接也分两种,读连接可调用SQLiteOpenHelper的getReadableDatabase方法获得,写连接可调用getWritableDatabase获得。
  • 关闭数据库连接:数据库操作完毕后,应当调用SQLiteDatabase对象的close方法关闭连接。

步骤03 提供对表记录进行增加、删除、修改、查询的操作方法。
可被SQLite直接使用的数据结构是ContentValues类,类似于映射Map,提供put和get方法用来存取键值对。区别之处在于ContentValues的键只能是字符串,查看ContentValues的源码会发现其内部保存键值对的数据结构就是HashMap“private HashMap<String, Object>mValues;”。ContentValues主要用于记录增加和更新操作,即SQLiteDatabase的insert和update方法。

对于查询操作来说,使用的是另一个游标类Cursor。调用SQLiteDatabase的query和rawQuery方法时,返回的都是Cursor对象,因此获取查询结果要根据游标的指示一条一条遍历结果集合。Cursor的常用方法可分为3类,说明如下:
1. 游标控制类方法,用于指定游标的状态。

  • close:关闭游标。
  • isClosed:判断游标是否关闭。
  • isFirst:判断游标是否在开头。
  • isLast:判断游标是否在末尾。

2. 游标移动类方法,把游标移动到指定位置。

  • moveToFirst:移动游标到开头。
  • moveToLast:移动游标到末尾。
  • moveToNext:移动游标到下一条记录。
  • moveToPrevious:移动游标到上一条记录。
  • move:往后移动游标若干条记录。
  • moveToPosition:移动游标到指定位置的记录。

3. 获取记录类方法,可获取记录的数量、类型以及取值。

  • getCount:获取结果记录的数量。
  • getInt:获取指定字段的整型值。
  • getFloat:获取指定字段的浮点数值。
  • getString:获取指定字段的字符串值。
  • getType:获取指定字段的字段类型。
SD卡文件操作

本节介绍Android的文件存储方式—— SD卡的用法,包括如何获取SD卡目录信息、公有存储空间与私有存储空间的区别、在SD卡上读写文本文件、在SD卡读写图片文件等功能。

SD卡的基本操作

手机的存储空间一般分为两块,一块用于内部存储,另一块用于外部存储(SD卡)。早期的SD卡是可插拔式的存储芯片,不过自己买的SD卡质量参差不齐,经常会影响App的正常运行,所以后来越来越多的手机把SD卡固化到手机内部,虽然拔不出来,但是Android仍然称之为外部存储。
获取手机上的SD卡信息通过Environment类实现,该类是App获取各种目录信息的工具,主要方法有以下7种。

  • getRootDirectory:获得系统根目录的路径。

  • getDataDirectory:获得系统数据目录的路径。

  • getDownloadCacheDirectory:获得下载缓存目录的路径。

  • getExternalStorageDirectory:获得外部存储(SD卡)的路径。

  • getExternalStorageState:获得SD卡的状态。
    SD卡状态的具体取值说明见表4-1。
    在这里插入图片描述

  • getStorageState:获得指定目录的状态。

  • getExternalStoragePublicDirectory:获得SD卡指定类型目录的路径。
    目录类型的具体取值说明见表4-2。
    在这里插入图片描述

为正常操作SD卡,需要在AndroidManifest.xml中声明SD卡的权限,具体代码如下:
在这里插入图片描述

公有存储空间与私有存储空间

本来在AndroidManifest.xml里面配置了存储空间的权限,代码就能正常读写SD卡的文件。可是Android从7.0开始加强了SD卡的权限管理,即使App声明了完整的SD卡操作权限,系统仍然默认禁止该App访问外部存储。
不过系统默认关闭存储其实只是关闭外部存储的公共空间,外部存储的私有空间依然可以正常读写。这是缘于Android把外部存储分成了两块区域,一块是所有应用均可访问的公共空间,另一块是只有应用自己才可访问的专享空间。之前讲过,内部存储保存着每个应用的安装目录,但是安装目录的空间是很紧张的,所以Android在SD卡的“Android/data”目录下给每个应用又单独建了一个文件目录,用于给应用保存自己需要处理的临时文件。这个给每个应用单独建立的文件目录,只有当前应用才能够读写文件,其他应用是不允许进行读写的,故而“Android/data”目录算是外部存储上的私有空间。这个私有空间本身已经做了访问权限控制,因此它不受系统禁止访问的影响,应用操作自己的文件目录就不成问题了。当然,因为私有的文件目录只有属主应用才能访问,所以一旦属主应用被用户卸载,那么对应的文件目录也会一起被清理掉。
既然外部存储分成了公共空间和私有空间两部分,这两部分空间的路径获取也就有所不同。获取公共空间的存储路径,调用的是Environment.getExternalStoragePublicDirectory方法;获取应用私有空间的存储路径,调用的是getExternalFilesDir方法。下面是分别获取两个空间路径的代码例子:
在这里插入图片描述

应用的私有空间路径位于“外部存储根目录/Android/data/应用包名/files/Download”这个目录之下。

文本文件读写

文本文件的读写一般借助于FileOutputStream和FileInputStream。其中,FileOutputStream用于写文件,FileInputStream用于读文件。文件输出输入流是Java语言的基础工具,这里不再赘述,直接给出具体的实现代码:
在这里插入图片描述

图片文件读写

Android的图片处理类是Bitmap,App读写Bitmap可以使用FileOutputStream和FileInputStream。不过在实际开发中,读写图片文件一般用性能更好的BufferedOutputStream和BufferedInputStream。
保存图片文件时用到Bitmap的compress方法,可指定图片类型和压缩质量;打开图片文件时使用BitmapFactory的decodeStream方法。读写图片的具体代码如下:
在这里插入图片描述

应用Application基础

本节介绍Android重要组件Application的基本概念和常见用法。首先说明Application的生命周期,接着利用Application的持久特性实现App内部全局内存中的数据保存和获取。

Application的生命周期

Application是Android的一大组件,在App运行过程中有且仅有一个Application对象贯穿整个生命周期。打开AndroidManifest.xml时会发现activity节点的上级正是application节点,只是默认的application节点没有指定name属性,不像activity节点默认指定name属性值为.MainActivity,让人知晓这个activity的入口代码是MainActivity.java。现在试试给application节点加上name属性,看看其庐山真面目。
(1)打开AndroidManifest.xml,给application节点加上name属性,表示application的入口代码是MainApplication.java。

android:name=".MainApplication"

(2)创建MainApplication类,该类继承自Application,可以重写的方法主要有以下4个。

  • Create:在App启动时调用。
  • onTerminate:在App退出时调用(按字面意思)。
  • onLowMemory:在低内存时调用。
  • onConfigurationChanged:在配置改变时调用,例如从竖屏变为横屏。
    (3)运行App,同时开启日志的打印。但是只在一开始看到MainApplication的onCreate操作(先于Activity的onCreate),却始终无法看到它的onTerminate操作,无论是自行退出还是强行杀死App的进程,日志都不会打印onTerminate。想在App退出前做资源回收操作,那么千万不要放在onTerminate方法中。
利用Application操作全局变量

C/C++有全局变量,因为全局变量保存在内存中,所以操作全局变量就是操作内存,内存的读写速度远比读写数据库或读写文件快得多。全局的意思是其他代码都可以引用该变量,因此全局变量是共享数据和消息传递的好帮手。不过,Java没有全局变量的概念。与之比较接近的是类里面的静态成员变量,该变量可被外部直接引用,并且在不同地方引用的值是一样的(前提是在引用期间不能修改该变量的值),所以可以借助静态成员变量实现类似全局变量的功能。
前面花费很大功夫介绍Application的生命周期,目的是说明其生命周期覆盖App运行的全过程。不像短暂的Activity生命周期,只要进入别的页面,原页面就被停止或销毁。因此,通过利用Application的持久存在性可以在Application对象中保存全局变量。
适合在Application中保存的全局变量主要有下面3类数据:
(1)会频繁读取的信息,如用户名、手机号等。
(2)从网络上获取的临时数据,为节约流量、减少用户等待时间,想暂时放在内存中供下次使用,如logo、商品图片等。
(3)容易因频繁分配内存而导致内存泄漏的对象,如Handler对象等。
要想通过Application实现全局内存的读写,得完成以下3项工作:
(1)写一个继承自Application的类MainApplication。该类要采用单例模式,内部声明自身类的一个静态成员对象,在创建App时把自身赋值给这个静态对象,然后提供该静态对象的获取方法getInstance。
(2)在Activity中调用MainApplication的getInstance方法,获得MainApplication的一个静态对象,通过该对象访问MainApplication的公共变量和公共方法。
(3)不要忘了在AndroidManifest.xml中注册新定义的Application类名,即在application节点中增加android:name属性,值为.MainApplication。
App把注册信息保存到MainApplication的全局变量中,然后在另一个页面从MainApplication的全局变量中读取保存好的注册信息。
在这里插入图片描述

完成以上编码后,Activity页面代码即可直接通过MainApplication.getInstance().mInfoMap对全局变量进行增、删、改、查操作。

内容提供与处理

本节介绍Android四大组件之一的ContentProvider的基本概念和常见用法。首先说明如何使用内容提供器封装数据的外部访问接口;接着阐述如何通过内容解析器在外部查询和修改数据,以及使用内容操作器完成批量数据操作;然后说明内容观察器的应用场合,并演示如何借助内容观察器实现流量校准的功能。

内容提供器ContentProvider

Android号称提供了4大组件,分别是页面Activity、广播Broadcast、服务Service和内容提供器ContentProvider。其中内容提供器是跟数据存取有关的组件,完整的内容组件由内容提供器ContentProvider、内容解析器ContentResolver、内容观察器ContentObserver这三部分组成。
ContentProvider为App存取内部数据提供统一的外部接口,让不同的应用之间得以共享数据。像我们熟知的SQLite操作的是应用自身的内部数据库;文件的上传和下载操作的是后端服务器的文件;而ContentProvider操作的是本设备其他应用的内部数据,是一种中间层次的数据存储形式。
在实际编码中,ContentProvider只是一个服务端的数据存取接口,开发者需要在其基础上实现一个具体类,并重写以下相关数据库管理方法。

  • onCreate:创建数据库并获得数据库连接。
  • query:查询数据。
  • insert:插入数据。
  • update:更新数据。
  • delete:删除数据。
  • getType:获取数据类型。
    这些方法看起来是不是很像SQLite?没错,ContentProvider作为中间接口,本身并不直接保存数据,而是通过SQLiteOpenHelper与SQLiteDatabase间接操作底层的SQLite。所以要想使用ContentProvider,首先得实现SQLite的数据表帮助类,然后由ContentProvider封装对外的接口。
    既然内容提供器是四大组件之一,就得在AndroidManifest.xml中注册它的定义,并开放外部访问权限,注册代码如下:
    在这里插入图片描述
    注册完毕后就完成了服务端App的封装工作,接下来可由其他App进行数据存取。
内容解析器ContentResolver

前面提到了利用ContentProvider实现服务端App的数据封装,如果客户端App想访问对方的内部数据,就要通过内容解析器ContentResolver访问。内容解析器是客户端App操作服务端数据的工具,相对应的内容提供器是服务端的数据接口。要获取ContentResolver对象,在Activity代码中调用getContentResolver方法即可。
ContentResolver提供的方法与ContentProvider是一一对应的,比如query、insert、update、delete、getType等方法,连方法的参数类型都一模一样。其中,最常用的是query函数,调用该函数返回一个游标Cursor对象,这个游标与SQLite的游标是一样的。
下面是query方法的具体参数说明(依顺序排列)。

  • uri:Uri类型,可以理解为本次操作的数据表路径。
  • projection:字符串数组类型,指定将要查询的字段名称列表。
  • selection:字符串类型,指定查询条件。
  • selectionArgs:字符串数组类型,指定查询条件中的参数取值列表。
  • sortOrder:字符串类型,指定排序条件。
内容观察器ContentObserver

ContentResolver获取数据采用的是主动查询方式,有查询就有数据,没查询就没数据。有时我们不但要获取以往的数据,还要实时获取新增的数据,最常见的业务场景是短信验证码。电商App经常在用户注册或付款时发送验证码短信,为了给用户省事,App通常会监控手机刚收到的验证码数字,并自动填入验证码输入框。这时就用到了内容观察器ContentObserver,给目标内容注册一个观察器,目标内容的数据一旦发生变化,观察器规定好的动作马上触发,从而执行开发者预先定义的代码。

总结一下在Content组件经常使用的系统URI,详细的URI取值说明见表4-3。
表4-3 常用的系统URI取值说明
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

五.海量数据实时分析-FlinkCDC+DorisConnector实现数据的全量增量同步

前言 前面四篇文字都在学习Doris的理论知识&#xff0c;也是比较枯燥&#xff0c;当然Doris的理论知识还很多&#xff0c;我们后面慢慢学&#xff0c;本篇文章我们尝试使用SpringBoot来整合Doris完成基本的CRUD。 由于 Doris 高度兼容 Mysql 协议&#xff0c;两者在 SQL 语法…

Redis数据库与GO(二):list,set

一、list&#xff08;列表&#xff09; list&#xff08;列表&#xff09;是简单的字符串列表&#xff0c;按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。List本质是个链表&#xff0c; list是一个双向链表&#xff0c;其元素是有序的&#xff0c;元…

GS-SLAM论文阅读笔记-CaRtGS

前言 这篇文章看起来有点像Photo-slam的续作&#xff0c;行文格式和图片类型很接近&#xff0c;而且貌似是出自同一所学校的&#xff0c;所以推测可能是Photo-slam的优化与改进方法&#xff0c;接下来具体看看改进了哪些地方。 文章目录 前言1.背景介绍GS-SLAM方法总结 2.关键…

uniapp+Android面向网络学习的时间管理工具软件 微信小程序

目录 项目介绍支持以下技术栈&#xff1a;具体实现截图HBuilderXuniappmysql数据库与主流编程语言java类核心代码部分展示登录的业务流程的顺序是&#xff1a;数据库设计性能分析操作可行性技术可行性系统安全性数据完整性软件测试详细视频演示源码获取方式 项目介绍 用户功能…

STM32F103C8----3-3 蜂鸣器(跟着江科大学STM32)

一&#xff0c;电路图 &#xff08;接线图&#xff09; 面包板的的使用请参考&#xff1a;《面包板的使用_面包板的详细使用方法-CSDN博客》 二&#xff0c;目的/效果 3-3 蜂鸣器 三&#xff0c;创建Keil项目 详细参考&#xff1a;《STM32F103C8----2-1 Keil5搭建STM32项目模…

Linux ssh 免密登录配置

参考资料 ~/.ssh/configについて~/.ssh/configを使ってSSH接続を楽にする.ssh/configファイルでSSH接続を管理する 目录 一. 密钥生成1.1 生成工具1.1.1 OpenSSH1.1.2 Git 1.2 生成命令1.3 注意事项1.4 解决路径中的用户名乱码 二. 将公钥配置到目标服务&#xff0c;免密登录2…

Spring Boot集成encache快速入门Demo

1.什么是encache EhCache 是一个纯 Java 的进程内缓存框架&#xff0c;具有快速、精干等特点&#xff0c;是 Hibernate 中默认的 CacheProvider。 Ehcache 特性 优点 快速、简单支持多种缓存策略&#xff1a;LRU、LFU、FIFO 淘汰算法缓存数据有两级&#xff1a;内存和磁盘&a…

Linux bash脚本 远程开发环境配置

参考资料 太香了&#xff0c;VSCode远程开发插件&#xff0c;值得一试Visual Studio Code で Remote SSH する。Managing extensions 目录 一. 远程开发必备二. 连接远程开发服务器三. 安装远程开发插件 一. 远程开发必备 ⏹ VSCode插件 Remote - SSH 通过使用 SSH 链接虚拟…

C++之多态篇(超详细版)

1.多态概念 多态就是多种形态&#xff0c;表示去完成某个行为时&#xff0c;当不同的人去完成时会有不同的形态&#xff0c;举个例子在车站买票&#xff0c;可以分为学生票&#xff0c;普通票&#xff0c;军人票&#xff0c;每种票的价格是不一样的&#xff0c;当你是不同的身…

如何高效删除 MySQL 日志表中的历史数据?实战指南

在处理高并发的物联网平台或者其他日志密集型应用时&#xff0c;数据库中的日志表往往会迅速增长&#xff0c;数据量庞大到数百GB甚至更高&#xff0c;严重影响数据库性能。如何有效管理这些庞大的日志数据&#xff0c;特别是在不影响在线业务的情况下&#xff0c;成为了一项技…

使用Windows远程桌面连接Linux

要在Kali Linux上使用Windows远程桌面连接&#xff08;MSTSC.exe&#xff09;&#xff0c;你可以通过配置xrdp服务来实现。以下是在Kali Linux上设置xrdp以便Windows远程桌面连接的具体步骤&#xff1a; 一、安装xrdp和Xfce桌面环境 更新软件包列表&#xff1a; 打开终端&…

Python和C++混淆矩阵地理学医学物理学视觉语言模型和算法模型评估工具

&#x1f3af;要点 优化损失函数评估指标海岸线检测算法评估遥感视觉表征和文本增强乳腺癌预测模型算法液体中闪烁光和切伦科夫光分离多标签分类任务性能评估有向无环图、多路径标记和非强制叶节点预测二元分类评估特征归因可信性评估马修斯相关系数对比其他准确度 Python桑…

基于C++和Python的进程线程CPU使用率监控工具

文章目录 0. 概述1. 数据可视化示例2. 设计思路2.1 系统架构2.2 设计优势 3. 流程图3.1 C录制程序3.2 Python解析脚本 4. 数据结构说明4.1 CpuUsageData 结构体 5. C录制代码解析5.1 主要模块5.2 关键函数5.2.1 CpuUsageMonitor::Run()5.2.2 CpuUsageMonitor::ComputeCpuUsage(…

大数据技术:Hadoop、Spark与Flink的框架演进

大数据技术&#xff0c;特别是Hadoop、Spark与Flink的框架演进&#xff0c;是过去二十年中信息技术领域最引人注目的发展之一。这些技术不仅改变了数据处理的方式&#xff0c;而且还推动了对数据驱动决策和智能化的需求。在大数据处理领域&#xff0c;选择合适的大数据平台是确…

有些硬盘录像机接入视频汇聚平台EasyCVR后通道不显示/显示不全,该如何处理?

EasyCVR视频监控汇聚管理平台是一款针对大中型项目设计的跨区域网络化视频监控集中管理平台。该平台不仅具备视频资源管理、设备管理、用户管理、运维管理和安全管理等功能&#xff0c;还支持多种主流标准协议&#xff0c;如GB28181、RTSP/Onvif、RTMP、部标JT808、GA/T 1400协…

排序算法剖析

文章目录 排序算法浅谈参考资料评价指标可视化工具概览 插入排序折半插入排序希尔排序冒泡排序快速排序简单选择排序堆排序归并排序基数排序 排序算法浅谈 参考资料 数据结构与算法 评价指标 稳定性&#xff1a;两个相同的关键字排序过后相对位置不发生变化时间复杂度空间复…

数据挖掘-padans初步使用

目录标题 Jupyter Notebook安装启动 Pandas快速入门查看数据验证数据建立索引数据选取⚠️注意&#xff1a;排序分组聚合数据转换增加列绘图line 或 **&#xff08;默认&#xff09;&#xff1a;绘制折线图。bar&#xff1a;绘制条形图。barh&#xff1a;绘制水平条形图。hist&…

QT将QBytearray的data()指针赋值给结构体指针变量后数据不正确的问题

1、问题代码 #include <QCoreApplication>#pragma pack(push, 1) typedef struct {int a; // 4字节float b; // 4字节char c; // 1字节int *d; // 8字节 }testStruct; #pragma pack(pop)#include <QByteArray> #include <QDebug>int main() {testStruct …

leetcode练习 路径总和II

给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum 22 输出&a…

告别传统互动:AI数字人正全面进入人类社会

大家好&#xff0c;我是Shelly&#xff0c;一个专注于输出AI工具和科技前沿内容的AI应用教练&#xff0c;体验过300款以上的AI应用工具。关注科技及大模型领域对社会的影响10年。关注我一起驾驭AI工具&#xff0c;拥抱AI时代的到来。 今天我们来聊聊AI数字人&#xff01; 当我…