20230504-onvif协议快速入门

1. 简介

onvif 最初的名称来自open network video interface forum 开放网络视频接口论坛,的首字母缩写,由于标准的范围扩展到视频应用程序之外,因此删除了 开放网络视频接口论坛 的名称,onvif 网络视频协议的出现,解决了不同厂商之间开发的各类设备不能融合使用的难题,提供了统一的网络视频开发标准,即最终能够通过onvif 这个标准化的平台实现不同产品之间的集成

onvif 主要是为网络视频产品提供标准化网络开放式接口,onvif 利用it 技术,例如soap rtp motion jpeg mpeg-4 和 h.264 视频解码功能,onvif 此后发布的规范2.0版本不仅具备存储功能,还具备分析功能,2018年10月,onvif 发布了profile T 支持H.265 视频解码功能

onvif 规范作用

onvif 规范描述了网络视频的模型、接口、数据类型以及数据交互的模式,并复用了一些现有的标准、如ws 系列标准等、onvif 规范的目标是实现一个网络视频框架协议,使不同厂商所生产的网络视频产品 包括 摄录前端、录像设备等,完全互通

onvif 规范的实现

onvif 规范中设备管理和控制部分所定义的接口均以web services 的形式提供,onvif 规范涵盖了完全的xml wsdl 的定义。每一个支持onvif 规范的终端设备均须提供与功能相应的web service 服务端与客户端的数据交互采用soap 协议,onvif 中的其他部分比如音视频流则通过RTP RTSP 进行

onvif 诡诞的优势

协同性 不同厂商所提供的产品,均可以通过一个统一的语言来进行交流,方便了系统的集成

灵活性 终端用户和集成用户不需要被某些设备的固有解决方案所束缚,大大降低了开发成本

质量保证,不断扩展的规范将由市场来导向,遵循规范的同时也满足了主流的用户需求

onvif 几个基本模块

设备发现 设备管理、设备输入输出服务、图像配置、媒体配置、实时流媒体、接收端配置、显示服务、事件处理、PTZ 控制、其他

2. 基于onvif 规范项目的开发基本流程

onvif 协议流程

客户端
请求服务

服务端

分析请求
处理请求
生成回应
soap 消息

服务端
回应请求

客户端根据wsdl 描述文档,会生成一个soap 请求消息,该请求会被嵌入在一个http post 请求中,发送到web services 所在的web 服务器,web services 请求处理器解析收到的soap 请求,调用相应的web services 然后再生成相应的soap 应答,web 服务器得到soap 应答后,会再通过http 应答的方式把信息送回到客户端

onvif 开发基本流程

获取WSDL 文件

通过gSOAP 编译为c c++ 文件

业务逻辑开发

编译发布

WSDL 文件

webservices description language WSDL web 服务语言是一个用于精确描述 web service 的xml 格式,wsdl 描述web 服务的公共接口,这是一个基于xml 的关于如何与web 服务通讯和使用的服务描述,也就是描述与目录中列出的web 服务进行交互时需要绑定的协议和信息格式,通常采用抽象语言描述该服务支持的操作和信息,使用的时候再将实际的网络协议和信息格式绑定给该服务

WSDL 元素基于xml语法描述了与服务进行交互的基本元素

type 消息类型 数据类型定义的容器,它使用某种类型系统,如XSD

message 消息,通信数据的抽象类型化定义,它由一个或者多个part 组成

part 消息参数

operation 操作 对服务所支持的操作进行抽象描述,wsdl 定义了四种操作

  1. 单向 端点接受信息,
    请求 响应 端点接受消息,然后发送相关消息

要求-响应,端点发送消息,然后接受相关消息

通知 端点发送消息

port type 端口类型,特定端口类型的具体协议和数据格式规范

binding 特定端口类型的具体协议和数据格式规范

port 定义为绑定和网络地址组合的单个端点

service 相关端口的集合,包括其关联的接口、操作、消息等

SOAP 协议

simple object access protocol 简单对象访问协议,是交换数据的一种协议规范,是一种轻量的、简单的、基于xml 标砖通用标记语言下的一个子集 的协议,它被设计成在web 上交换/传递结构化和固化的信息,包含下列元素

必需的envelope 元素,可把此xml 文档标识为一条soap 消息

可选的header 元素,包含头部信息

必需的body 元素,包含所有的调用和响应信息

可选的fault 元素,提供有关在处理此消息所发生错误的信息

在向web service 发送的soap请求中,body 元素中的字段需与wsdl 中的数据类型相符合,在构建soap的过程中,必须从wsdl 文件中获取并映射这一种对应关系,然而这样一个对应过程将是一个充满了重复性和机械性的,为了避免不必要的人工差错以及节约开发时间、一个名为gSOAP的编译工具应用而生

soap 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议 http 简单邮件传输协议,SMTP 多用途网际邮件扩充协议 MIME 它还支持从消息系统到远程过程调用 RPC 等大量的应用程序,soap 使用基于xml 的数据结构和超文本传输协议 http 的组合定义了一个标准的方法来使用internet 上各种不同操作环境中的分布式对象

把soap 绑定到http 提供了同时利用soap 的样式和分散的灵活性的特点以及http 的丰富的特征库的优点,在http 上传送soap 并不是说soap 会覆盖现有的http 语义而是http 上的soap 语义会自然的映射到http 语义,在使用http 作为协议绑定的场合中,RPC 请求映射到http 请求上,而RPC 应答映射到http 应答,然而,在rpc 上使用soap 并不仅限于http 协议绑定,soap 也可以绑定到TCP 和udp 协议上

gSOAP

gSOAP 编译工具提供了一个soap/xml 关于c/c++ 语言的实现,从而让c/c++语言开发web 服务或客户端程序的工作变得轻松了很多,绝大多数的c++ web 服务工具包提供一组api 函数类库来处理特定的soap 数据结构,这样就使得用户必须改变程序结构来适应相关的类库,与之相反,gsoap 利用编译器技术提供了一组透明化的soap api ,并将与开发无关的soap 实现细节相关的内容对用户隐藏起来

gSOAP 的编译器能够自动的将用户定义的本地化的c 或c++ 数据类型转变为复合xml 语法的数据结构,反之亦然,这样,只用一组简单的api 就将用户从soap 细节实现工作中解脱了出来,可以专注与应用程序逻辑的实现工作了

web service

soap 协议
TCP UDP 协议

IP 网络协议

物理链路层

onvif 规范的实现机制

web service 是基于网络的、分布式的模块化组件,执行特定的任务,web service 主要利用http 和soap 协议使数据在web 上传输,web 用户能够使用soap 和http 通过web 调用的方法来调用远程对象,即 xml 被用作数据描述的语法,soap 用于消息传递,wsdl 用来描述服务,基于web 服务开发原理如下

上图对web 服务开发的基本原理进行了概括,服务提供者 设备实现 onvif 的服务或者其他服务,这些服务从用基于xml 的wsdl 语言进行描述,然后,由wsdl 描述的文档将作为服务请求,客户端 实现或者整合的基础,wsdl 编译工具的使用简化了客户端的整合过程,wsdl 编译工具能生成与平台相关的代码即、客户端开发者可通过这些代码把web 服务整合到应用中

  1. web service 与视频监控

onvif 规范向视频监控引入了web service 的概念,设备的实际功能均被抽象为了web service 的服务,视频监控系统的控制单元以客户端的身份出现,通过web 请求的形式完成控制操作

  1. 应用

PU 设备上线后,向cmu 发送hello 消息

cmu 需要搜寻设备时,向PU 发送probe 消息

cmu 与pu 进行信令交互,请求能力集,获取配置

cu 上线,向cmu 注册,建立连接

cmu 与cu 进行信令交互,传输设备列表

在cmu 的协调下,cu 同 pu 建立连接传输码流

在上述的场景中,通过onvif ,pu 与cmu 的交互方式发生了改变,cmu 不再与pu 保持长连接,遵循onvif 规范,信令以及消息内容有了统一的标准

CMU 即中心管理单位

PU 即监控前端单元,负责在cmu的控制下使用摄像机采集视频流,使用麦克风采集音频流,使用控制口采集报警信息,对摄像机云台镜头进行控制

cmu+pu 服务器 如安防相机

cu 监控系统的监控客户端单元


Profile 文件、附加组件及规范

onvif 致力于为安防行业提供并促进标准化接口,实现物理ip 安防产品有效交互操作性

20230420-NTFS,FAT32和exFAT文件系统有什么区别

当用户在windows 平台上插入新的u盘 或移动硬盘时,系统会自动弹出需要格式化的窗口,提供了3种不同文件格式 NTFS FAT32 exFAT

很多用户对这3种格式知之甚少,只是根据弹窗的指示进行操作,windows 也没有对3种格式提供详细的解释,本文会对这些问题进行详细解释

首先需要明白什么是文件系统

文件系统是系统对文件的存放排列方式,不同格式的文件系统关系到数据是如何在磁盘进行存储,文件名、文件权限和其他属性也存在不同,windows 操作系统支持ntfs fat32 和exFAT 三种不同文件系统,ntfs是目前windows 系统中一种现代文件系统,目前使用最广泛,内置的硬盘大多数都是ntfs 格式,fat32 是一种相对老旧的文件系统,不能像ntfs 格式支持很多现代文件格式的属性,但对于不同系统平台具有良好的兼容性,可以在linux mac 或android 系统平台上通用

exFAT 是FAT32 文件格式的替代品,很多设备和操作系统都支持该文件系统,但是目前用的不多

3种文件格式的不同

Fat32 文件格式是一种通用格式,任何usb存储设备都会预装该文件系统,可以在任何操作系统平台上使用,最主要的缺陷是只支持最大单文件大小容量为4GB,因此日常使用没有问题,只有在传输大文件时才会显现出缺点

exFAT 是微软自家创建的用来取代FAT32文件格式的新型文件格式,它最大可以支持1EB 的文件大小,非常适合用来存储大容量文件,还可以在mac 和windows 操作系统上通用,虽然是微软的技术,苹果批准在系统中使用该文件格式,因此在mac 系统中格式化存储设备时会出现exFAT 文件格式选项

最大的缺点是没有文件日志功能,这样就不能记录磁盘上文件的修改记录

  1. NTFS 是微软为硬盘或固态硬盘SSD 创建的默认新型文件系统,NTFS 的含义是new technology file system 它继承了所有文件系统的优点
    日志功能,无文件大小限制,支持文件压缩和长文件名,服务器文件管理权限等,最大的缺点是mac 系统只能读取ntfs 文件但没有权限写入,需要借助第三方工具才能实现,因此跨平台的功能非常差

========

设备管理—–文件管理

文件和进程os 引入的两个重要概念

文件的概念

文件概述

概念

文件是具有符号名的,在逻辑上具有完整意义的一组相关的信息项的序列
文件 document 与计算机文件file 具有一定区别
文件名是由字母 数字和其他符号组成的一个字符串,其格式和长度因系统而异

文件命名

文件命名一般包括文件名和扩展名

前者用于识别文件,后者用于标识文件特性,两者之间用圆点隔开

每个os 都有约定的扩展名

文件分类

按用途分

系统文件 库文件 用户文件

按保护级别分

只读文件 读写文件 不保护文件

按信息时限分

临时文件 永久文件 档案文件

按设备类型分

磁盘文件 磁带文件 光盘文件,软盘文件

文件优点

用户使用方便

使用者无需记住信息存放在辅存的物理位置,也无需考虑如何将信息存放在存储介质上,只要知道文件名,给出有关os 要求便可存取信息,实现了按名存取

文件安全可靠

由于用户通过文件系统才能实现对文件的访问,而文件系统能提供各种安全 保密和保护措施,故而防止对文件信息的有意或无意的破坏或窃用

可备份

可组织转储或备份,在文件使用go锤死出现硬件故障时,文件系统可组织重置,提高可靠性

可共享

文件系统还能提供文件的共享功能,如不同的用户可以使用同名或异名的同一文件,提高了文件和文件空间的利用率

因此,把数据组织成文件形式加以管理和控制是计算机数据管理的重大进展

5.2 文件系统及其功能

文件系统

文件系统概念 文件

文件系统的概念

文件系统是os 中负责存取和管理信息的模块,它用统一的方式管理用户和系统信息的存储、检索、更新、共享和保护,并为永辉提供一整套方便有效的文件使用和操作方法

文件系统中的文件
文件这一术语不但反映了用户概念中的逻辑结构,而且和存放它的辅助存储器 的存储结构紧密相关

因此一个文件必须从逻辑文件和物理文件两个侧面来观察它

文件系统功能

面向用户功能

  1. 文件的按名存取
  2. 文件的共享和保护
  3. 文件的操作和使用

OS 需要考虑的内容 —- 实现文件系统

  1. 文件目录的建立和维护
  2. 存储空间的分配和回收
    数据的保密和保护

监督用户存取和修改文件的权限
实现在不同存储介质上信息的表示方式 编址方法 存储次序 以及信息检索等问题

文件系统组成

文件系统

文件的组织

组织方法 逻辑结构 流式文件 记录式文件

物理结构 顺序文件 连接文件 直接文件 索引文件

文件的存取 存取方法 顺序存取 直接存取 索引存取

文件的控制 控制系统 逻辑的控制系统 物理的控制系统

文件的使用 文件操作 打开文件 关闭文件 读写 控制

5.3 文件的存储

文件的存储

卷和块的概念
顺序存取存储设备 磁带 光盘
直接存取存储设备 磁盘

卷和块

常见的文件存储介质有磁带 光盘 和磁盘

卷是存储介质的物理单位,对应于一盘磁带,一块软盘,一个光盘片 一个硬盘分区


块是存储介质上连续信息所组成的一个区域,也叫物理记录

块在磁盘上被称之为扇区,而在磁带和光盘上则被称之为一个块

块是主存储器和辅助存储器进行信息交换的物理单位,每次总是交换一块或整数块信息

块大小

决定块的大小要考虑用户使用方式、数据传输效率和存储设备类型等多种因素

不同类型的存储介质,块的长短常常各不相同,对同一类型的存储介质,块的大小通常来说都相同,但也可以不同,取决于具体情况

外围设备由于启停机械动作或识别不同块的要求,两个相邻块之间必须留有间隙

间隙是块之间不同记录用户代码信息的区域

顺序存取存储设备

顺序存取设备是严格依赖信息的物理位置次序进行定位和读写的存储设备,常见的顺序存取设备有磁带 光盘

磁带

磁带机是最常用的一种顺序存取存储设备,它具有存储容量大,稳定可靠,卷可装卸和便于保存等优点,广泛用作存档

5.3.3 直接存取存储设备

磁盘是一种典型的直接存取存储设备,又叫随机存取存储设备

磁盘

磁盘拥有移臂和旋转两维结构,存取速度高,它的每个物理记录都有确定的位置和唯一的地址,但其存取物理块所需时间随机,而且相差不大,几乎不依赖此信息的位置

5.4 文件的逻辑结构

文件的逻辑结构

逻辑文件概念

两种文件逻辑结构

流式文件

记录式文件

记录式文件与数据库的区别

逻辑文件概念

逻辑文件概念

逻辑文件,又称为文件的逻辑结构

独立于物理环境的,用户概念中的抽象信息组织方式

用户能观察到的,并加以处理的数据集合

两种文件逻辑结构

流式文件

记录式文件

5.4.2 流式文件
指文件内的数据不再组成记录,只是由一串依次的字节组成的信息流序列

这种文件常常按长度来读取所需信息,也可以用插入的特殊字符作为分界

注意 流式文件不具有多维信息结构,只是单纯的连续字符串存取

记录式文件

记录式文件是一种有结构的文件,它是若干逻辑记录信息所组成的记录流文件

逻辑记录是文件中按信息在逻辑上的独立含义所划分的信息单位

例如,每个职工的工资信息是一个逻辑记录,整个单位职工的工资信息便组成了该单位工资信息的记录式文件

记录式文件 vs 数据库

数据库管理系统也支持逻辑记录,但数据库与记录式文件最大的区别在于,数据库可以通过一些表与表的数据冗余构成表间关系,并基于这些联系进行数据查询,而文件系统不行

5.5 文件的物理结构

文件的物理结构

物理结构概念

四种文件物理结构

顺序文件 只能从头开始访问的数组

连接文件 链表

直接文件 哈希

索引文件 索引表 多级索引

物理结构概念

文件的物理结构和组织是指文件在物理存储空间中的存放方法和组织关系,又称为物理文件

文件的存储结构涉及块的划分、记录的排列、索引的组织、信息的搜索等问题

文件物理结构的优劣直接影响文件系统的性能

顺序文件

物理结构

类似于一个只能从头开始访问的数组

将一个文件中逻辑上连续的信息存放到存储介质的依次相邻的块中,构成顺序结构,这类文件叫顺序文件,也称为连续文件

顺序文件通常存储在同一个柱面上,减少移臂开销

磁带文件 光盘文件是顺序文件的典型

优点

顺序存取记录时速度较快,常用于批处理文件、系统文件

采用磁带存放顺序文件时,总可以保持快速存取的又掉

缺点

建立文件前需要能预先确定文件长度,以便分配存储空间,修改、插入和增加文件具有困难

连接文件

物理结构

连接文件是对于顺序文件存储空间连续的一种修改,采用链表方式使得存储空间不连续,但访问顺序依然连续

连接文件,又称串联文件,使用连接字来表示文件中各个物理块之间的先后次序

第一块文件信息的物理地址由文件目录给出,而每一块的连接字指出了文件的下一个物理块位置,连接字内容为0时,表示文件至本块结束

输入井 输出井都使用此类文件

优点

易于对文件记录做增删改 易于动态增长记录

不必预先确知文件长度

存储空间利用率高

缺点

存放指针需额外的存储空间 但浪费空间少

连接文件仅适用于顺序存取,找第100个文件必须经过前99个文件,对于顺序存取文件可以接受,但对于随机存取文件则不可接受

5.5.4 直接文件

采用了哈希方法进行文件映射,主要难点在于哈希冲突

直接文件,又称散列文件,通过计算记录的关键字建立与其物理存储地址之间的对应关系

哈希冲突

计算寻址结构可能出现冲突,即不同个毽子映射相同地址,常见解决方法有拉链法、循环探查法、二次散列法,溢出区法

5.5.4 索引文件

物理结构

索引文件为每个文件建立了一张索引表,其中,每个表目包含一个记录的键 逻辑记录号 及其存储地址

索引表的地址可由文件目录指出,查阅索引表先找到相应记录键,然后获得数据存储地址

访问方式

索引文件在文件存储器上分为两个区 索引区 数据区

查找索引表

获得记录物理地址

上述过程需要两次访问辅存,若文件索引已预先调入主存,则仅需一次内外存信息交换

优点

索引结构可以被认为是连接结构的一种扩展,除了具备连接文件的优点外,还克服了顺序存取的缺点,具有直接读写任何一个记录的能力,便于文件的增删改

缺点 增加了索引表的时空开销

多级索引结构

5.6 文件的目录结构

文件目录结构概念

三种文件目录结构

一级目录结构
二级目录结构
树形目录结构

文件目录

文件目录概念

文件目录是实现文件的按名存取的关键数据结构

文件系统的基本功能之一就是负责文件目录的建立、维护和检索,要求编排的目录便于查找、防止冲突

文件目录需要永久保存,因此也组织成文件存放在磁盘上,称目录文件

文件目录与索引文件的区别

文件目录是面向用户设计的数据结构,目的是为了让用户可以按名存取 文件

索引文件是os用来查找文件物理位置的数据结构,用户不可见

一级目录结构

在os 中构造一张线性表,与每个文件的相关属性占用一个目录项,构成了一级目录结构

但由于用户与文件众多,不但容易重名,而且用户难以查找

二级目录结构

目录结构

第一级是主文件目录,管理所有用户文件目录,目录项登记了系统接受的用户的名字,以及该用户文件目录的地址

第二级为用户的文件目录,为该用户的每个文件保存一个登记栏,其内容与一级目录的目录项相同

每一用户只允许查看自己的文件目录

优点

  1. 支持检查访问文件者的存取权限,实现了文件的保密和保护,因为任何文件的存取都必须通过主文件目录

  2. 允许不同用户出现同名文件

树形目录结构

目录结构

每一级目录可以登记下一级目录,也可以登记文件,从而形成了层次文件目录结构

层次目录结构通常采用树形目录结构,树根是根目录,树叶是文件

优点

较好地反映现实世界中具有层次关系的数据集合和较确切地反映系统内部文件的组织结构

不位于同一末端子目录的不同文件可以重名

易于规定不同层次或子树中文件的不同存取权限,便于文件的保护,保密和共享

文件定位

在树形目录结构中,一个文件的全名包括从根目录开始到文件为止,通路上遇到的所有子目录路径,又称为路径名

各子目录名之间用斜线隔开 unix 用正斜线,windows 用反斜线

一个硬盘分区可以组织成一棵子树

每棵子树可以对应于一个逻辑盘符 win

也可以把多棵子树合并成一棵大数 unix

举例
/
bin
ls
who
date
cp
cc
unix

user

lib user bin
etc
passwd
rc
ttys
mount
volcopy
group
tsck
tskh

tmp
dev
ttyo1
ttyo2
console
rrk
lp
lnern

目录文件
特别文件
普通文件

5.7 文件目录的管理

文件目录的管理

文件查找
多层找一层

根目录
当前目录
变更目录

一层找一个

顺序查找
二分
哈希

活动文件表
文件目录部分缓存

5.7.1 文件查找

文件查找分为两步
定位层次 定位具体目录项

文件层次定位

根据用户提供的文件路径名来搜索各级文件目录,找到文件

从根目录查起 绝对路径名
从当前目录查起 相对路径名

. 表示当前目录
.. 表示父目录

  1. 变更当前工作目录 现代os 设置有改变工作命令

目录项查找

顺序查找法

二分查找法

将按键进行顺序编排,即可进行二分

  1. 哈希法

将每个文件名经过变换函数变换成唯一的目录表表项

5.7.2 活动文件表

树型目录结构存在问题

当一个文件经过许多目录节点时,系统需要多次访问文件存储器,文件查找非常耗时

解决方法

采用 cache 的方法,将部分常用或正在用的文件目录复制进主存,实现部分缓存的目的

活动文件表

系统为每个用户进行建立一张活动文件表,当用户使用一个文件之前,先通过 打开操作,把该文件有关目录信息复制到指定主存区域,有关信息填入活动文件表,以建立用户进程和该文件索引的联系

当不再使用该文件时,使用关闭 ,切断用户进程和这个文件的联系,同时,若该目录已被修改过,则应更新辅存中对应的文件目录

5.8 文件安全

文件安全概念

文件共享
文件保护
文件保密

文件共享 文件共享的并发控制

文件保护

文件副本 动态多副本 转储备份

文件存取矩阵与文件存取表 用户-文件-权限

文件属性 对用户进行分类 设置文件属性

文件保密 隐藏文件 文件口令 文件内容加密

5.8.1 文件安全概念

文件是计算机系统的重要资源,因此要求文件系统具有保障文件安全的手段,提供文件保密的措施,有效地实现文件共享

文件安全三大内容

文件共享 不同用户共同使用某些文件

文件保护 防止文件被破坏

文件保密 防止文件及其内容被其他用户窃取

5.8.2 文件共享

文件共享概念

文件共享是计算机用户完成共同任务所必需的

文件共享有许多好处

减少用户大量重复性劳动

免除系统复制文件的工作

节省文件占用的存储空间

减少程序设计输入输出文件的次数

文件共享的并发控制

os应该提供手段实现对共享文件的同步控制

同时读:os 对文件进行公用控制

一读一写 os 提供同步控制机制,保证数据的完整性

同时写 不被允许

文件保护

文件保护概念

文件保护是指防止文件被破坏,os 必须提供文件保护机制,有效实现文件的完整性

常用的文件保护方法

文件副本

文件副本即存储多个文件副本,保证即使硬件软件故障,信息仍能完整保存

动态多副本技术

在多个介质上维持同一内容的文件,并且同时更新内容

这种方法需要增加设备费用和系统负载,一般适用于容量较小且较为重要的文件,例如不需要更新的系统文件及专用文件,当文件发生故障时只要切换到备用设备即可

这种方法是精细活,执行起来非常累

文件转储 大多数os 采用

文件转储 定时把文件复制转储到其它介质上,当某介质上出现故障时,复原转储文件,转储分为两种方式

在一定时间间隔或一个单位处理结束时,系统自动复写更新过的文件和数据

只能针对少量的关键数据

每天或每周把文件信息全部复写一遍,需要时再通过装入转储文件来恢复系统,诸如 backup restore 等命令

通常需要系统管理员手动备份

文件的存取控制矩阵表

os 为每个用户设置访问每个文件对象的存取属性,即用户 文件 权限 三元组的关系

所有三元组就组成了一个二维矩阵,称为存取控制矩阵

存取控制表

由于操作系统拥有很多用户和众多软件,因此存取控制矩阵是一个稀疏矩阵,存在大量无效位置

因此我们将无效位置删除,仅登记那些对文件拥有存取属性的部分,将二维矩阵优化成一维线性表,即存取控制表

基于存取控制矩阵/表的文件保护

存取属性 访问 读写 执行 创建 删除 授权

一些非常安全的os 甚至设计了20多种属性

系统通过查阅矩阵 表来核对用户对文件的存取权限

文件属主使用grant revoke 等命令进行授权,甚至授权授权权

系统管理用户 超级用户 拥有所有文件的属主权限

5.8.3.4 文件属性 广泛采用

该方法是将原来的三位结构简化为 用户-文件 二维结构,大为简化文件管理

具体方式

用户分类 属主、合作者、其他

文件属性 读写 执行

每个用户对于每个文件都有三种身份,不同身份对于不同文件属性权限不同

文件属性可以放在文件目录项中,简化管理

用户使用文件时,根据该用户针对该文件的用户类别,以及文件属性,核对用户权限,实现保护

chmod 吗,命令可以改变文件属性

chown 命令可以变更文件属主

chgrp 命令可以变更用户伙伴

5.8.4 文件保密

文件保密是指文件及其内容不能被未经文件主授权的其他用户窃取

文件保密常见措施

  1. 隐藏文件目录
    将关键文件设置为隐藏文件 保密程度弱

  2. 设置口令

在文件层面设置 读写 打开口令

这种方式较第一种有升级,但拦不住那些直接访问磁盘物理数据的恶意用户

  1. 使用密码

对文件内容进行加密,只有拿到密钥才能解密 保密程度强

5.9 文件的存取方法

文件系统的一个重要目标,尽可能地提供不同的存取方法

文件存取方法是os 为用户程序提供的使用文件的技术和手段

文件存取方法在某种程度上依赖于文件的物理结构

文件的存取方法

顺序存取
直接存取
索引存取

5.9.1 顺序存取

概念

按记录顺序进行读写操作的存取方法称顺序存取

读操作根据读指针读出当前记录,同时推进读指针,指向下一次要读出的记录

写操作设置写指针,把一个记录写到文件末端,同时推进写指针

允许对读指针进行前跳或后退n个记录的操作

适用范围

顺序存取方式对任何物理结构文件均适用

直接存取

支持直接文件、索引文件的物理结构能进行直接存取,直接存取针对那些要求快速地以任意次序直接读写某个记录的应用场合

例如,例如航空订票系统,把航班号作标识,把特定航班的所有信息存放在物理块中,用户预定某航班时,直接计算出该航班的存取位置

索引存取
基于索引文件的物理结构,才能实现索引存取,其中信息块的地址都可以
通过查找记录建而换算出

特点

索引文件,支持顺序、直接、索引三种存取方式

实际的系统中,大都采用多级索引,来加速记录查找过程

5.10 文件的使用

文件的使用

文件使用方法

操作命令

cat cd cp find mv rm mkdir rmdir

系统调用

建立 打开 读写 定位 关闭 撤销

系统调用实现方式

建立文件
撤销文件
打开文件
关闭文件
读写文件

定位文件

5.10.1 文件使用方法

用户通过两类接口与文件系统联系

  1. 与文件有关的操作命令

unix 中的cat cd cp find mv rm mkdir rmdir

提供给用户程序使用的文件类系统调用

建立 打开 读写 定位 关闭 撤销

5.10.2 建立文件

功能 创建一个文件

所需参数 文件名 设备类 号 文件属性 存取控制信息

处理流程

  1. 若文件没有关闭,关闭文件
    若为共享文件,进行联访处理

在目录文件中删去相应目录项
释放文件占用的文件存储空间

5.10.4 关闭文件

功能 结束一个文件的读写

所需参数 文件句柄

处理流程

将活动文件表中该文件的当前使用用户数 减1
若此值为0,则收回此活动文件表
完成 推迟写

若活动文件表目内容已被改过,应先将表目内容写回文件存储器中相应表目位置,以使文件目录保持最新状态

读写文件

功能 读写文件

所需参数 文件句柄,用户数据区地址,读写的记录或字节个数

处理流程

  1. 按文件句柄从活动文件表中找到该文件的目录项信息

根据目录项指出的该文件逻辑和物理组织结构,把相关逻辑记录转换成物理块

5.10.6 定位文件

功能 调整所打开文件的读写指针位置

所需参数:文件句柄,定位指针

辅存空间管理

随着用户文件不断建立和撤销,文件存储空间会出现许多碎片,

os 解决碎片的办法是整理碎片,在整理过程中,往往对文件重新组织,让其存放在连续存储区中

辅存空间管理

辅存空间分配方式

连续分配

非连续分配

空闲块的管理

成组链接法

辅存空间分配方式

连续分配

特点,存放在辅存空间连续存储区 廉租的物理块号

优点 顺序访问时速度快,管理较为简单,但为了获得足够大的连续存储区,需定时进行 碎片 整理

非连续分配

特点 动态分配给若干扇区或簇 几个连续扇区,不要求连续

优点 辅存空间管理效率高,便于文件动态增长和收缩

空闲块的管理

位示图

方式 使用若干字节构成一张表,表中每一字位对应一个物理块,字位的次序与块的相对次序一致,字位为1 表示相应块已占用,字位为0 表示该块空闲

优点,把位示图全部或大部分保存在主存中,再配合位操作,实现高速物理块分配和去配

成组链接法

从下图中可以看到,最左边的是空闲盘块号栈,12为栈,50为栈底,栈底块链接到右边的100个空闲块,可以看到最后一个栈底为0,表示空闲盘块链的结束

注意,最左边的空闲盘块栈中的块始终保持在1,100 之间

下图算法中,空闲块数即空闲盘块栈中记录的空闲块数

复制第1个单元对应块到专用块,表示一次性将51 150 都复制进来,并分配50

如果归还空闲块数超过100,则留下第101个,移走前100个,并将第101个链接到移走的100个上

5.12 文件系统的实现层次

  1. 检查用户发起的系统调用
    逻辑记录 相对物理地址
    检查用户权限
    相对物理地址 绝对物理地址
    具体物理块io操作

用户接口

接受用户发来的系统调用,进行语法检查,进入逻辑文件控制子系统

逻辑文件控制子系统

根据文件路径名,搜索文件目录,建立活动文件表,根据文件结构和存取方法,把逻辑记录转换成相对物理块号和块内相对地址

文件保护子系统

识别调用者的身份,验证存取权限,判定本次文件操作的合法性

物理文件控制子系统

实现缓冲区管理,根据物理结构,将相对物理块号转换为实际物理块号,负责文件存储空间的分配,生成io控制系统的调用形式

io控制子系统

执行具体的物理块io操作

20230419-C++文档doxygen/breathe语法

本手册用来给megengine 开发者提供常见的c++接口文档的语法模板作为参考,帮助其高效地撰写和修改复合megengine 工程规范的面向用户的c++接口文档

不是所有的doxygen 语法都能在megengine 文档中被使用,我们仅使用它来提取信息,而用breathe 来构建文档,

一份参考模块

下面这个例子改自Breathe 官方文档的nutshell 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
* @file nutshell.h
*
* @brief This is a nutshell example.
*/

/*!
* With a little bit of a elaboration, should you feel it necessary.
*/
class Nutshell
{
public:

//! Our tool set
/*! The various tools we can opt to use to crack this particular nut */
enum Tool
{
kHammer = 0, //!< What? It does the job
kNutCrackers, //!< Boring
kNinjaThrowingStars //!< Stealthy
};

//! Nutshell constructor
Nutshell();

//! Nutshell destructor
~Nutshell();

/*! Crack that shell with specified tool
*
* @param tool - the tool with which to crack the nut
*/
void crack( Tool tool );

/*!
* @return Whether or not the nut is cracked
*/
bool isCracked();

private:

//! Our cracked state
bool m_isCracked;

};

注意事项

多行注释中带有前导星号 leading-asterisk * 而非单纯的空行

使用@param 代替\param 写法,避免遇到后者形式在其他解析工具中被转义的情况

MegEngine 文档只要是公开接口、成员,不论是否有相应备注,都会生成对应的api 文档

使用breathe 语法

breathe 文档中提供了一些简单的语法模板,可以在c++接口文档中添加数学公式、列表、表格等样式,在简单情况下可以使用

参考breathe features 页面中给出的各种样例

对于比较复杂的文档内容编辑和排版需求,推荐使用下一小节提到的ReST 语法,即 MegEngine 文档中最常使用的语法

使用ReST 语法和组件

MegEngine文档中使用了比较多的sphinx 拓展样式,使用时通过resTructuretext 语法来解析,当默认的样式不满足需求时,可以使用sphinx restructuretext 语法入门中展示的各种语法作为拓展,但需要注意的是,由于使用了前导星号,为了能够被正常解析,需要使用 embed:rst:leading-asterisk 标记

1
2
3
4
5
6
7
8
9
/*!
* Inserting additional reStructuredText information.
*
* \verbatim embed:rst:leading-asterisk
* .. note::
*
* This is a example.
* \endverbatim
*/

它等同于在C++ 接口文档中插入了如下ReST语法

1
2
3
.. note::

This is a example.

会得到对应的note 样式块内容,同理,你还可以使用这种方法来插入 数学公式和图片等等内容

从源码到文档的流程

MegEngine 的C++源码经历了如下流程变成megengine 文档中的api 参考页面

C++ head files doxygen xml files breathe directive sphinx rst doc

由于MegEngine 文档与MegEngine 源码不再同一处维护,因此开发人员通常会规律性地使用doxygen 从MegEngine 的c++ 源码中生成最新的xml 文件,位于doxyxml 目录中,平时撰写文档只需要使用breathe 将xml 中的信息转换成sphinx 的rst 文档,体验上与从 MegEngine 的python package 生成api 文档类似

以tensor 为例子,添加python 接口和c++接口 生成文档的sphinx 语法对比如下

1
2
3
.. autoclass:: megengine.Tensor

.. doxygenclass:: lite::Tensor

使用自动生成的文档的好处之一是,方便在文档其他的任何地方进行引用

1
比如此处直接引用 :class:`megengine.Tensor` 与 :cpp:class:`lite::Tensor` 的 API 文档。

详细的sphinx 和breathe 文档语法对比


Breathe 文档

breathe 在sphinx 和doxygen 文档系统之间提供了一座桥梁

这是一个简单的方法,将doxygen 信息包含在由sphinx 生成的一组文档中,目的是为那些喜欢使用sphinx 但用python 以外的语言工作的人制作一个类似autodoc的支持,该系统依赖于doxygen的xml输出

警告

这个文档的构建不是来自于breathe的一个特定的标记版本,它反映了breathe的工作进展状态,请参阅github 仓库 https://github.com/michaeljones/breathe ,以获得更多的官方信息

概述

简单的设置,一个doxygen 配置值,一个sphinx 配置值和一个指令,你就可以上路了

高级和低级指令,引用整个项目,只是一个类或只是一个函数的不同指令

支持多个doxygen 项目,将其设置为知道不同的项目,并在每个指令中通过名称或路径引用它们

允许在doxygen 标记中嵌入reStructureText 一些额外的doxygen 别名允许你在评论中添加 rst endrst 块,并将内容解释为reStructureText

对sphinx 域的基本支持,用标准的sphinx 域引用链接到breathe输出中的函数

设置与使用

快速入门

Directives Config Variables
与doxygen 和autodoc的差异

running on Read the docs

特性

Supported markups

latex math
domains

custom css
groups
lists
tables

template

贡献

contribute to breathe

how it works
credits

示例 测试页面

test pages

下载

breathe 可从以下网站获得

pypi the python package index
github

简而言之

你写的代码看起来有点像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/**
\file nutshell.h
An overly extended example of how to use breathe
*/

/*!
With a little bit of a elaboration, should you feel it necessary.
*/
class Nutshell
{
public:

//! Our tool set
/*! The various tools we can opt to use to crack this particular nut */
enum Tool
{
kHammer = 0, //!< What? It does the job
kNutCrackers, //!< Boring
kNinjaThrowingStars //!< Stealthy
};

//! Nutshell constructor
Nutshell();

//! Nutshell destructor
~Nutshell();

/*! Crack that shell with specified tool

\param tool - the tool with which to crack the nut
*/
void crack( Tool tool );

/*!
\return Whether or not the nut is cracked
*/
bool isCracked();

private:

//! Our cracked state
bool m_isCracked;

};

然后你运行这个

1
doxygen

有一个设置是这样说的

1
GENERATE_XML = YES

然后在你的 Sphinx 文档中,你可以添加这样的内容

1
2
3
.. doxygenclass:: Nutshell
:project: nutshell
:members:

通过像这样的 conf.py 设定

1
2
3
breathe_projects = {
"nutshell":"../../examples/specific/nutshell/xml/",
}

并在 conf.py 中把 Breathe 注册为一个插件,像这样

1
extensions = [ "breathe" ]

你会得到类似这样的东西:


  • class Nutshell

    With a little bit of a elaboration, should you feel it necessary.Public Typesenum Tool Our tool set.The various tools we can opt to use to crack this particular nutValues:enumerator kHammer What? It does the job.enumerator kNutCrackers Boring.enumerator kNinjaThrowingStars Stealthy.Public Functions**Nutshell() Nutshell constructor.~Nutshell() Nutshell destructor.void crack(Tool tool) Crack that shell with specified tool参数tool – the tool with which to crack the nutbool isCracked() 返回Whether or not the nut is cracked


================

快速入门

对于这个快速入门,我们假设有以下先决条件

在某处下载并提取了breathe
已经安装了doxygen 并且为要记录的项目生成了doxygen xml 格式 将 GENERATE_XML 标签设为 YES

我们假设有以下的路径

文档根路径
breathe 路径

doxygen xml 输出路径

文档路径应该包含一个文件夹source 其中包含conf.py 文件,doxygen xml 输出文件夹应该包含index.xml 由doxygen 生成的输出文件

要整合breathe 功能,需要采取以下步骤

在你的 conf.py 中添加breathe 路径,方法是添加以下一行

sys.path.append( “/home/me/docproj/ext/breathe/“ )

添加 breathe 作为插件,这一行可以这样写

extensions = [‘sphinx.ext.pngmath’, ‘sphinx.ext.todo’, ‘breathe’ ]

告诉 breathe 关于项目的信息

breathe_projects = { “myproject”: “/home/me/docproj/doxyxml/“ }

指定默认的项目

breathe_default_project = “myproject”

一旦完成这些工作,你可以使用以下命令

1
2
3
4
5
6
.. doxygenindex::
.. doxygenfunction::
.. doxygenstruct::
.. doxygenenum::
.. doxygentypedef::
.. doxygenclass::

以包括不同结构的文档,对于这些命令中的每一条,都可以指定以下指令

project 指定哪个项目,如breathe_projects 配置值中定义的,应该用于该指令,这取代了默认值

path
直接指定到有doxygen 输出的文件夹的路径,这覆盖了project 和default project


指令和配置变量

指令和配置变量

directives 指令

doxygenclass
doxygendefine
doxygennum
doxygennumvalue
doxygenfile
autodoxygenfile
doxygenfunction
doxygengroup
doxygenindex
autodoxygenindex
doxygennamespace
doxygenstruct
doxygeninterface
doxygentypedef
doxygenunion
doxygenvariable
doxygenpage

config values 配置值

指令

可用的指令如下所示,在每种情况下,project path no-link 和outline 选项具有以下含义

project 指定配置值中定义的项目,应该用于此指令,这将覆盖默认项目 如果有,已指定 breathe_projects

指令不使用此功能,改为用于指定配置值中的条目来使用 autodoxygenindexsourcebreathe_projects_source

path 直接指定具有doxygen 输出的文件夹的路径,这覆盖项目和默认项目 如果已指定

指令不使用此功能,改为用于指定要成为的源文件的根路径 autodoxygenindexsource-path

no-link 指示 breathe 不要尝试为此特定指令生成的内容

这使您可以将主要参考列表放在具有以下位置的某个位置目标,但随后能够将重复指令潜入其他指令,

部分文档来说明将特定要点,但没有sphinx 对其他参考资料应该链接到什么感到困惑

outline 导致breathe 仅输出原始代码定义,而无需任何其他描述信息

如果指令上既没有提供项目也没有提供路径,那么breathe 将 breathe_default_project 配置值为设置

此指令为单个类生成适当的输出,它采用标准项目、路径、大纲和无链接选项,此外还有 members protected-members private-members undoc-members membergroups 和members-only 选项

1
2
3
4
5
6
7
8
9
10
11
.. doxygenclass:: <class name>
:project: ...
:path: ...
:members: [...]
:protected-members:
:private-members:
:undoc-members:
:membergroups: ...
:members-only:
:outline:
:no-link:

重看 doxygenclass 文档以获取更多详细信息 并看到它的实际效果

doxygendefine

此指令为单个预处理器生成适当的输出定义,它的行为与doxygenstruct 指令相同

1
2
3
4
5
.. doxygendefine:: <define name>
:project: ...
:path: ...
:outline:
:no-link:

重看示例以查看其实际效果

doxygenenum

此指令为单个枚举生成适当的输出,它的行为与doxygenstruct 指令相同

1
2
3
4
5
.. doxygenenum:: <enum name>
:project: ...
:path: ...
:outline:
:no-link:

doxygenenumvalue
此指令为单个枚举值生成适当的输出

doxygenfile
此指令为源的内容生成适当的输出文件

autodoxygenfile
此指令是上述doxygenfile 指令的此版本,它像其他自动指令一样为您处理doxygen xml 生成auto

查看示例以查看其实际效果

doxygenfunction

此指令为单个函数生成适当的输出,这个函数名称在项目中是唯一的

doxygengroup
此指令为doxygen 的内容生成适当的输出群,可以使用特定的doxygen 标记声明doxygen 组来源注释如 doxygen 分组文档中所述

它采用标准的project path outline 和no-link 选项和content-only members protected-member private-members undoc-members 选项

查看 doxygengroup 文档以获取更多详细信息,并看到它的实际效果

doxygenindex

该指令处理并生成由 doxygen xml 输出,它读取文件并处理所有内容 由它引用 index.xml

autodoxygenindex

此指令执行与指令类似的角色,除了它为您处理doxygen xml 生成,它使用配置字典来判断哪个代码源文件应具有为其生成doxygen xml 该指令选项将指令与字典中的特定项目相关联,中条目引用的所有文件将包含在输出中,此外,任何中指定的选项将添加到生成的doxygen 配置文件和中指定的任何自定义别名都将添加到 doxygen 别名中

doxygennamespace

此指令为命名空间的内容生成相应的输出

It takes the standard project, path, outline and no-link options and additionally the content-only, members, protected-members, private-members and undoc-members options.

要引用嵌套命名空间,必须提供完整的命名空间路径,例如,对于命名空间内的命名空间, foo::bar bar

查看doxygennamespace 文档了解更多信息,细节并查看它的实际效果

doxygenstruct
此指令为单个结构生成适当的输出,结构体名称在项目中必须是唯一的

It takes the standard project, path, outline and no-link options and additionally the members, protected-members, private-members, membergroups, members-only and undoc-members options.

查看示例以查看其实际效果

doxygeninterface

此指令为单个接口 专门使用 类,它的行为与doxygenclass 指令相同

doxygentypedef

此指令为单个typedef 生成适当的输出,它的行为与doxygenstruct 指令相同

doxygenunion

此指令为单个联合生成适当的输出,它的行为与doxygenstruct 指令相同

doxygenvariable

此指令为doxygen 的内容生成适当的输出页,为每个使用xrefitem 命令的每个键创建一个doxygen页面用于源注释中的标记,有关详细信息,请查看doxygen外部参照文档

它采用标准 project 和 path 选项,以及 content-only选项,

查看doxygenpage 文档以获取更多详细信息,并看到它的实际效果

config values
breathe_projects

这应该是一个字典,其中键是项目名称,值是包含该项目的doxygen 输出的文件夹的路径

breathe_default_project

这应该与字典中的一个键匹配,并且指示在未指定项目时应该使用哪个项目指令

breathe_domain_by_extension

允许您根据特定文件的域指定域外框

breathe_domain_by_file_pattern
允许您通过通配符语法为特定文件指定域,这之后被检查,因此将覆盖必要时

如果您希望将所有头文件都视为在cpp 域中,您可以使用以下示例 以上,但是,如果您有一个文件应被视为在c 域中,那么您可以如上所述进行覆盖,

breathe_projects_source

其中键是项目名称,值是元组的字典的目录和这些目录的源代码文件名列表,您希望使用doxygen 自动处理的项目,如果您在以下位置有一些文件

1
2
/some/long/path/to/myproject/file.c
/some/long/path/to/myproject/subfolder/otherfile.c

然后,您可以设置

1
2
3
4
breathe_projects_source = {
"myprojectsource" :
( "/some/long/path/to/myproject", [ "file.c", "subfolder/otherfile.c" ] )
}

然后,您的 autodoxygenfile 使用情况可能如下所示

1
2
.. autodoxygenfile:: file.c
:project: myprojectsource

元组中的目录条目可以是空字符串,如果,列表是完整路径

breathe_build_directory

为了处理breathe,必须运行以创建要处理xml 文件,此配置值指定根应在其中创建这些文件的目录,默认情况下,这设置为输出文件夹的父目录,即正常构建目录,如果您有自定义,则可以使用此设置进行更改,

breathe 将采用最终值并附加到路径以最大程度地减少冲突

breathe_default_members

提供应用于所有指令的指令标志 采取 和选项,默认情况下,此选项设置为空列表,这意味着没有成员显示,如果您想始终显示公众和公众,无文档成员,那么您可以像这样设置它

breathe_default_members = (‘members’, ‘undoc-members’)

breathe_implementation_filename_extensions
提供被视为实现文件,当指令查找未命名的函数名称时,将忽略这些文件,这是为了避免问题标头的doxygenxml 输出中出现相同的函数名称 文件和实现文件,因为声明在一个和定义在另一个,doxygen 将文档从定义到声明的xml 因此我们不会错过任何文档 来自实现文件的信息,此值的默认值 变量为 doxygenfunction

breathe_implementation_filename_extensions = [‘.c’, ‘.cc’, ‘.cpp’]

breathe_doxygen_config_options

一个字典,其中键和值是配置的名称和值,要放置在由 autodoxygenindex 生成的doxygen 配置文件中的选项

breathe_doxygen_config_options = {‘EXCLUDE_SYMBOLS’: ‘abc123’}

将放置在配置文件中,默认值为空字典,exclude_symbols=abc123

breathe_doxygen_aliases

其中键和值是别名的名称和值的字典,放置在由 autodoxygenindex 生成的doxygen 配置文件中

breathe_doxygen_aliases = {‘rstref{1}’: r’\verbatim embed:rst:inline :ref:\1 \endverbatim’}

将放置该行

ALIASES += rstref{1}=”\verbatim embed:rst:inline :ref:\1 \endverbatim”

在配置文件中,默认值为空字典,请注意使用原始字符串以确保反斜杠解释为文字字符,此示例别名允许使用 rstref

breathe_show_define_initializer

一个布尔标志,可以设置为在输出中显示定义的初始值设定项 true

例如,如果将定义 MAX_LENGTH 100 设置为值为100 True 不带则为false

breathe_show_enumvalue_initializer

一个布尔标志,可以设置为在输出中显示枚举值的初始值设定项,True

例如,如果将枚举值设置为 TWO=2 为true 否则为false

breathe_show_include

一个布尔标志,可以设置为隐藏每个标头定义实体 结构 函数,宏 等 false

例如,当设置为 True struct foo 将呈现

但当设置为false 时,将呈现

breathe_use_project_refids

真或假设置,用于控制呼吸氧气是否产生的反射元素是否包含项目名称,旧版 行为是所有refid 都以项目名称为前缀,这导致尝试在多个项目之间链接文档时出现问题,因为项目无法看到彼此的文档元素,新的默认行为是不在refid 前面加上项目名称

breathe_use_project_refids = True

如果需要,将恢复旧行为

breathe_order_parameters_first

True或false 设置,用于控制是否从doxygen 生成的参数部分 文档应紧跟在 简短和详细的描述之后,或在最后,在返回,备注和警告部分之后,默认值和旧行为也是false

breathe_separate_member_pages

True 或false 设置,用于控制doxygen 生成的输入xml 是否具有 doxygen separate_member_pages 选项设置为是或否,doxygen 选项末尾到no 生成允许breathe 解析所有引用的xml 设置时是的,元素 refid 得到一个额外的元素,呼吸试图摆脱它,当此设置为True 时

20230418-Doxygen快速入门

我们在编写代码的时候,最头疼的就属于说明书了,很多代码一边写具体代码,一边写说明书,doxygen 主要解决说明书问题,可以在我们写代码的时候讲注释转化为说明书,graphviz 主要是用于图形展示,html help workshop 主要使用生成 CHM 文档

doxygen
doxygen 能将程序中的特定批注转换成为说明文件,它可以依据程序本身的结构,将程序中按规范注释的批注经过处理生成一个纯粹的参考手册,通过提取代码结构或借助自动生成的包含依赖图
继承图 以及协作图来可视化文档之间的关系,doxygen 生成的帮助文档的格式可以是 CHM RTF Postscript PDF HTML 等

graphiviz

graphiviz 是一个由AT&T 实验室启动的开源工具包,用于绘制dot 语言脚本描述的图形,要使用doxygen 生成依赖图,继承图以及协作图,必须先安装 graphiviz 软件

HTML help workshop

微软出品的HTML help workshop 是制作chm 文件的最佳工具,它能将HTML文件编译生成chm 文档,doxygen 软件默认生成HTML文件或latex 文件,我们要通过HTML生成chm 文档,需要先安装 HTML help workshop 软件,并在doxygen 中进行关联

见示例效果图

配置

我们的所有配置都在doxywizard 中进行,生成参考手册是通过运行doxywizard 得到

wizard > project

最重要的是工作目录,源代码目录,生成参考文件目录三处的设定,其他项目名称,项目简介、版本和标识可以依照实际情况选填

工作目录是新建一个目录,在配置完成之后可以把配置文件存在这个目录里,每次从这个目录中导入配置文件 cfg 然后进行说明文档生成

源代码目录和最终的结果目录在每一次运行doxywizard 时都进行设定

wizard > mode

选择编程语言对应的最优化结果,按照编程语言选择

wizard > output

选择输出格式,选HTML下的chm 选项,为最后生成chm 做准备,由于不需要latex 结果,不选此项

wizard > diagrams
选择 dot tool 项 通过graphviz 来作图

expert > project

选择输出目录,选择输出语言,如果代码中采用了中文注释,此处选择为中文

向下拉滑条,看见有JAVADOC_AUTOBRIEF和QT_AUTOBRIEF两个框,如果勾选了,在这两种风格下默认第一行为简单说明,以第一个句号为分隔;如果不选,则需要按照Doxygen的指令@brief来进行标准注释。

Expert > input

将输入编码方式改为gbk 确保输出中不会由于utf-8 导致乱码

最后也是经常遇到的问题就是doxygen 生成的chm文件的左边树目录的中文变成了乱码,这个只需要经chm索引的编码 的编码类型修改为 gb2312 即可,在HTML 的chm_index_encoding中输入gb2312 即可

Expert HTML

勾选 生成 HTMLhelp项,输入生成chm 名称,在 HHC_LOCATION中填入HTMLHELP WORKSHOP 安装目录中 hhc.exe 的路径,将chm 编码方式改为gbk 方式,与第6步中的输入编码方式一致

Expert->Dot

在dot_PATH 中填写 graphiviz 的安装路径

需要在build 中配置 extract_all 和local_methods 才能生成所有的变量和函数

  1. 存储配置信息

存储配置信息,到上一步doxygen 已经完全配置好,可以在run 中点击运行了,但为了保存以上配置信息,可以将配置好的文件存一个 .cfg 文件,之后再运行 doxygen 时 只需要将该文件用 doxygen 打开,改变第一步中的输入,输出目录及工程的信息再运行, file save as 取一个名,默认为doxygen,加 .cfg 点击保存,如果需要改变配置文件,改动之后再save 替换之前的配置文件即可

  1. Run Run Doxygen

即可运行doxygen 运行完成后在输出目录中的HTML文件夹中找到index.chm 文件即为输入代码的说明文档

规范

规范综述

简单的说,doxygen 注释块其实就是在C C++ 注释块的基础添加一些额外标识,使doxygen 把它识别出来,并将它组织到生成的文档中去

在每个代码项 中都可以有两类描述,一种就是brief 描述,另一种就是detailed ,两种都是可选的

但不能同时没有,简述 brief 就是在一行内简述地描述,而详细描述 detailed 则提供更长,更详细的文档

在doxygen 中,主要通过以下方法将注释块标识成详细detailed 描述

javadoc 风格,在C 风格注释块开始使用两个星号 *

1
2
3
4
/**
* ... 描述 ...
*
*/

Qt 风格代码注释,即在C风格注释块开始处添加一个叹号!

1
2
3
4
/**
* ... 描述 ...
*
*/

使用连续两个以上 C++ 注释行所组成的注释块,而每个注释行开始处要多写一个斜杠或写一个叹号

1
2
3
///
/// ... 描述 ...
///

同样的,简要说明 brief 有也有多种方式标识,这里推荐使用@brief 命令强制说明,例如

1
2
3
/** 
* @brief 简要注释Brief Description.
*/

注意以下几点

Doxygen 并不处理所有的注释,doxygen 重点关注与程序结构有关的注释,比如 文件、类、结构、函数、全局变量,宏等注释,而忽略函数内局部变量 代码等的注释

注释应写在对应的函数或变量前面,javadoc 风格下,自动会把第一个句号 . 前的文本作为简要注释,后面的为详细注释,你也可以用开航把简要注释和详细注释分开,注意要设置
JAVADOC_AUTOBRIEF或者QT_AUTOBRIEF设为YES。

先从文件开始注释,然后是所在文件的全局函数、结构体、枚举变量,命名空间 – 命名空间中的类 成员函数和成员变量

doxygen 无法为dll 中定义的类导出文档

常用指令

指令说明

@file 档案的批注说明

author 作者的信息
brief 用于class 或function 的简易说明 eg: @brief 本函数负责打印错误信息串

param 主要用于函数说明中,后面接参数的名字,然后再接关于该参数的说明

return 描述该函数的返回值情况 eg @return 本函数返回执行结果,若成功则返回true 否则返回false

retval 描述返回值类型

note 注解

attention 注意

warning 警告信息

enum 引用了某个枚举 doxygen 会在该枚举处产生一个链接 @enum CTest::MyEnum
var 引用了某个变量 doxygen会在该枚举处产生一个链接

class 引用某个类,格式 @class [][]eq:@class CTest “inc/class.h”

exception 可能产生的异常描述 eg: @exception 本函数执行可能会产生超出范围的异常

模块

modules 是一种归组things 在分离的page 上的方式,组的成员可以是file namespace classes functions variables enums typedefs 和defines 但也可以是其他groups

要定义一个group 应该在一个特殊注释块放置 \defgroup 命令的第一个参数应该是唯一标志该group 的标签,要将一个entity 归为某个group 的一个member 在entity前放置 \ingroup 命令

第二个参数是group 的title

要避免在注释中每个member 前放置\ingroup 命令可以将member 用@{ 和@} 封装起来,@{@} 标记可以放置group的注释中,也可以在一个独立的注释块

使用这些group的标记符号 groups 也可以嵌套

如果多次使用一个group 标签,将会出错,如果不希望doxygen强性执行唯一标签,可以使用 addtogroup 而非 defgroup 运作方式和defgroup 很像,但是如果该group 已经定义,它默认向已存在的注释中添加一个新的项,group 的title 对此命令是可选的,也可以考虑使用它

1
2
3
4
5
6
7
/*
* @defgroup 模块名 模块的说明文字
* @{
*/
... 定义的内容 ...
/** @} */
// 模块结尾这样可以在其他地方以更加详细的说明添加members到一个group。

如果一个compound 例如一个class 或file 有多个members ,通常我们希望将其group doxygen 已经可以自动按照类型和protection 级别将这些things 归组在一起,但可能你会认为仅仅这样是不够的或者这种缺省的方法是错误的,例如你认为有不同语法的类型需要归入同一个group 语意

这样定义一个member group

1
2
3
//@{ 
...
//@}

块或者使用

1
2
3
/*@{*/ 
...
/*@}*/

注释实例

  1. 文件注释

举例说明如下,在代码文件头部写上这段注释,可以看到可以标注一些文本名称、作者、邮件、版本、日期、介绍以及版本详细记录

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* @file sensor.c
* @author JonesLee
* @email Jones_Lee3@163.com
* @version V4.01
* @date 07-DEC-2017
* @license GNU General Public License (GPL)
* @brief Universal Synchronous/Asynchronous Receiver/Transmitter
* @detail detail
* @attention
* This file is part of OST. \n
* This program is free software; you can redistribute it and/or modify \n
* it under the terms of the GNU General Public License version 3 as \n
* published by the Free Software Foundation. \n
* You should have received a copy of the GNU General Public License \n
* along with OST. If not, see <http://www.gnu.org/licenses/>. \n
* Unless required by applicable law or agreed to in writing, software \n
* distributed under the License is distributed on an "AS IS" BASIS, \n
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n
* See the License for the specific language governing permissions and \n
* limitations under the License. \n
* \n
* @htmlonly
* <span style="font-weight: bold">History</span>
* @endhtmlonly
* Version|Auther|Date|Describe
* ------|----|------|--------
* V3.3|Jones Lee|07-DEC-2017|Create File
* <h2><center>&copy;COPYRIGHT 2017 WELLCASA All Rights Reserved.</center></h2>
*/

  1. 类和成员注释
1
2
3
4
5
6
7
/**
* @class <class‐name> [header‐file] [<header‐name]
* @brief brief description
* @author <list of authors>
* @note
* detailed description
*/

如果对文件、结构体、联合体、类或者枚举的成员进行文档注释的话,并且要在成员中间添加注释,而这些注释往往都是在每个成员后面,为此,可以使用在注释段中使用< 标识

1
int var; /**< Detailed description after the member */

对一个类的注释例子如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Test
{
public:
/** @brief A enum, with inline docs */
enum TEnum
{
TVal1, /**< enum value TVal1. */
TVal2, /**< enum value TVal2. */
TVal3 /**< enum value TVal3. */
}
*enumPtr, /**< enum pointer. */
enumVar; /**< enum variable. */
/** @brief A constructor. */
Test();
/** @brief A destructor. */
~Test();
/** @brief a normal member taking two arguments and returning an integer value. */
int testMe(int a,const char *s);

/** @brief A pure virtual member.
* @param[in] c1 the first argument.
* @param[in] c2 the second argument.
* @see testMe()
  1. 函数注释
    直接看案例如下,见明知意 不再赘述
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/**
* @brief can send the message
* @param[in] canx : The Number of CAN
* @param[in] id : the can id
* @param[in] p : the data will be sent
* @param[in] size : the data size
* @param[in] is_check_send_time : is need check out the time out
* @note Notice that the size of the size is smaller than the size of the buffer.
* @return
* +1 Send successfully \n
* -1 input parameter error \n
* -2 canx initialize error \n
* -3 canx time out error \n
* @par Sample
* @code
* u8 p[8] = {0};
* res_ res = 0;
* res = can_send_msg(CAN1,1,p,0x11,8,1);
* @endcode
*/
extern s32 can_send_msg(const CAN_TypeDef * canx,
const u32 id,
const u8 *p,
const u8 size,
const u8 is_check_send_time);
  1. 枚举注释
    直接看案例如下,见明知意 不再赘述

    1
    2
    3
    4
    5
    6
    /** bool */  
    typedef enum
    {
    false = 0, /**< FALSE 0 */
    true = 1 /**< TRUE 1 */
    }bool;
  2. 全局变量和宏

  3. 模块注释

group 定义命令的优先级 从高到低 \ingroup \defgroup \addtogroup \weakgroup 而\weakgroup 很像一个有低优先级的\addtogroup 它被设计为实现一个lazy 的group 定义方法,可以在.h 文件中使用高优先级来定义结构,在.cpp 文件中使用\weakgroup 这样不会重复.h 文件中的层次结构

在实际使用中,我们可以看到具体的网页展示如下

在图中有个BSP 下的LED模块,这个模块就是承载驱动文件LED ,具体代码如下,为了显示效果,我把函数的注释删除了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
* @file led.h
* @author JonesLee
* @email Jones_Lee3@163.com
* @version V4.01
* @date 07-DEC-2017
* @license GNU General Public License (GPL)
* @brief Controller Area Network
* @detail detail
* @attention
* This file is part of OST. \n
* This program is free software; you can redistribute it and/or modify \n
* it under the terms of the GNU General Public License version 3 as \n
* published by the Free Software Foundation. \n
* You should have received a copy of the GNU General Public License \n
* along with OST. If not, see <http://www.gnu.org/licenses/>. \n
* Unless required by applicable law or agreed to in writing, software \n
* distributed under the License is distributed on an "AS IS" BASIS, \n
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \n
* See the License for the specific language governing permissions and \n
* limitations under the License. \n
* \n
* @htmlonly
* <span style="font-weight: bold">History</span>
* @endhtmlonly
* Version|Auther|Date|Describe
* ------|----|------|--------
* V3.3|Jones Lee|07-DEC-2017|Create File
* <h2><center>&copy;COPYRIGHT 2017 WELLCASA All Rights Reserved.</center></h2>
*/
/** @addtogroup BSP
* @{
*/
/**
* @brief Light Emitting Diode
*/
/** @addtogroup LED
* @{
*/
#ifndef __LED_H__
#define __LED_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "bsp.h"
extern s32 led_init(Led_TypeDef led);
extern s32 led_config(void);
extern s32 led_on(Led_TypeDef led);
extern s32 led_off(Led_TypeDef led);
extern s32 led_toggle(Led_TypeDef led);
#ifdef __cplusplus
}
#endif
#endif /*__LED_H__ */
/**
* @}
*/
/**
* @}
*/
/******************* (C)COPYRIGHT 2017 WELLCASA All Rights Reserved. *****END OF FILE****/

前面说明了是C语言的,C语言没有继承一说,在C++中有时候需要展示继承,如图

20230418-用sphinx快速制作文档

Sphinx 快速制作文档

简介

sphinx 是一种文档工具,它可以令人轻松的撰写出清晰且优美的文档,由georg brandl 在bsd 许可证下开发,新版的python文档就是由sphinx 生成的,并且它已成为python项目的首选的文档工具,同时它对c++项目也有很好的支持,并计划对其他开发语言添加特殊支持,本站当然也是使用sphinx 生成的,它采用 reStructuredText Sphinx 还在继续开发,下面列出了其良好特性,这些特性在python官方文档中均有体现

丰富的输出格式,支持HTML 包括windows 帮助文档,latex 可以打印PDF版本,manual pages man 文档,纯文本

完备的交叉引用,语义化的标签,并可以自动化链接函数,类,引文,术语及相似的片段信息

明晰的分层结构 可以轻松的定义文档树,并自动化链接同级 父级 下级文章

美观的自动索引 可自动生成美观的模块索引

精确的语法高亮 基于pygments 自动生成语法高亮

开放的扩展,支持代码块的自动测试,并包含python模块的自述文档 api docs 等

sphinx 使用reStructureText 作为标记语言,可以享有docutils 为restructureText 提供的分析,转换等多种工具

安装sphinx

sphinx 为python 语言的一个第三方库,我们需要在终端中输入下列命令进行安装

pip install sphinx

创建 sphinx 项目

创建一个用于存放文档的文件夹,然后在该文件夹路径下运行下列命令快速生成sphinx 项目

sphinx-quickstart

接下来会让你选择一些配置

设置文档的根路径 回车 使用默认设置

是否分离source 和build 目录

设定模板前缀 回车 使用默认选项

输入项目名称和作者

输入项目版本号

文档语言 回车 默认即可

设定文档就按的后缀

设定首页名称 回车 选择默认index 即可

根据需要选择是否开启 epub 输出 一般用不到 回车默认不开启即可

根据需求选择是否开启相应的sphinx 拓展功能

创建项目以后目录结构如下所示

build 用来存放通过make html 生成文档网页文件的目录

source 存放用于生成文档的源文件

conf.py sphinx 的配置文件

index.rst 主文档

定义文档结构

主文档 index.rst 的主要功能是被转换成欢迎页,它包含一个目录表 table of contents tree 或者 toctree sphinx 主要功能是使用reStructureText 把许多文件组织成一份结构合理的文档

toctree 指令初始值如下

你可以在content 的位置添加文档列表

注 文档文件放在与index.rst 同级目录下

支持markdown 文件、更改文档主题

spinx 本身不支持md 文件生成文档,需要我们使用第三方库 recommonmark 进行转换,首先分别运行下列命令安装 recommonmark 与sphinx_rtd_theme 库

pip install recommonmark

pip install sphinx_rtd_theme

a安装好 在conf.py 中修改下列两个配置

并新增

1
2
3
4
source_parsers = {
'.md': CommonMarkParser,
'.MD': CommonMarkParser,
}

生成文档

在sphinx 项目所在的文件夹路径下运行下列命令生成文档

make html

生成后的文档位于 build/html 文件夹内,用浏览器打开index.html 即可看到生成后的文档

20230410-什么是DHCP?总结DHCP优缺点和工作原理

了解DHCP或动态主机配置协议

DHCP 是动态主机配置协议的缩写,它是一种存在于应用层的网络管理协议,在DHCP 的帮助下,可以动态地给网络上的任何设备或节点分配一个互联网协议ip 地址,使它们可以使用这个ip 进行通信,网络管理员的任务是将大量的ip 地址手动分配给网络中的所有设备,然而,在DHCP 中,这个任务是自动化的,是集中管理,而不是手工管理,无论是小型本地网络还是大型企业网络都实现了DHCP DHCP 的基本目标是为主机分配一个唯一的ip地址

子网掩码

路由器地址

DNS 地址

供应商类别标识符

DHCP 有两种不同的方式,即作为客户端和服务器

DHCP的历史

DHCP 是bootp的扩展版本,也是1985年开始的一个网络管理协议,DHCP 服务器有足够的能力处理来自 BOOTP 客户端的请求,不仅如此,与BOOTP 相比,DHCP 更先进

DHCP 是如何工作的

当DHCP服务器作为服务器时,DHCP 服务器是用来自动分配唯一的ip 地址,同时配置网络的其他信息,在小型企业或家庭中,DHCP 服务器除了路由器之外,没有其他任何一个是DHCP 服务器,然而,在大型网络中,DHCP 服务器可以是一台计算机

在这个过程中发生了什么,简单的总结如下,

客户端向主机发送一个ip 地址请求,客户端可以是任何发送请求的设备,主机可以是路由器,主机将寻找一个可用的ip地址并分配给客户端

使用这个ip 地址,客户端就可以在网络上进行通信

现在我们就来详细了解一下这个过程,下面提到的步骤可以深入了解一下

连接到有DHCP 服务器的网络的设备发送的请求称为 DHCPDISCOVER 请求

这个请求以一个名为discover 的数据包的形式发送给DHCP 服务器,DHCP 服务器收到这个数据包,服务器就会立即寻找设备使用的ip 地址,一旦找到后,服务器会通过向客户端发送一个名为DHCPoffer 的数据包进行响应

设备或客户端现在必须用一个名为 DHCPrequest 的数据包回馈给服务器,以接受所选的ip 地址,对于这个数据包,服务器会立即寻找设备使用的ip 地址,一旦找到后,服务器会通过向客户端发送一个名为dhcp offer 的数据包进行响应

设备或客户端现在必须用一个名为dhcprequest的数据包回馈给服务器,以接受所选的ip 地址,对于这个数据包,服务器会发送一个确认 ack 确认设备现在可以使用这个特定的ip 地址,它还声明了特定 ip 地址的有效性,这样设备就能准确地知道何时必须获得一个新的ip 地址

如果服务器不希望设备拥有给定的ip地址,它将不会通过发送一个nac来确认设备的请求

虽然上面提到的步骤看起来很费时间,但实际操作起来却非常快,让人不自觉地就会想到,当然,这个过程不需要技术上的细节,只需阅读就可以从dhcp 服务器上获得一个ip 地址

DHCP 是如何让工作变得轻松

DHCP 服务器有一个地址池,可以让设备获得有效的网络连接,它基本上给出了谁be接收地址的范围,或范围内的ip 地址

DHCP 有用的第二个原因是,很多设备可以在指定的时间段内连接到一个网络,甚至不需要任何可用的地址池,例如,考虑20个地址由DHCP 服务器定义 40 80 100 的设备只要不超过20个地址同时使用其中一个可用的ip 地址就可以连接到网络

像ipconfig 这样的的命令在使用dhcp 时,会随着时间的推移返回不同的ip 地址,因为这些地址是提供给你的计算机网络的,在指定的时间段内也称为租期,拥有手动分配ip 地址的设备不一定能与动态接收ip 地址的设备在同一网络中共存,手动分配的ip 地址也称为静态ip 地址

DHCP 的优缺点

DHCP 的优点和缺点如下

优点

DHCP 有很多好处,因此它非常受欢迎,以下是使用dhcp 的一些优点

可以很容易地在网络中添加新的客户端

ip 地址是由 dhcp 集中管理的

ip 地址可以重复使用,从而减少了对ip 地址总数的要求

DHCP 服务器上的ip 地址空间可以很容易地进行重新配置,而不需要单独重新配置客户端

网络管理员可以利用 dhcp 协议提供的方法,从集中区域配置网络

缺点

就像每一个硬币都有它的优点和缺点一样,使用DHCP 也有以下缺点

在将ip 地址分配给不同的主机时,有时会出现ip 地址冲突的情况

总结

动态主机配置协议是一个非常关键和重要的网络服务,是必须要有的,因为使用它可以帮助你作为一个系统管理员或网络管理员,通过分配、跟踪和重新分配ip 来处理客户端,离开管理,此外,如果有任何外提,你只需要保持与服务器连接,并验证设置,而不是在客户端之间运行

20230403-如何用python分析股票

一个基本的股市分析项目,旨在了解金融市场 python编程的一些基本知识,让你5分钟上手股票可视化分析,

导入必要的模块

我们导入numpy pandas 和用于作图的matplotlib 库

第一部分

从雅虎财经获取特斯拉 通用和福特的每日收盘价数据

第二部分 可视化数据,并对有趣的事情进行可视化检查,在本节中,我们还将从头开始教你怎样画蜡烛图

在同一张图中画出特斯拉 通用和福特股票的开盘价曲线

每只股票的最大成交量是在哪一天

从开盘价格的时间序列可视化来看,似乎特斯拉的股价一直都要比通用和福特的股价更有高,但至于为什么特斯拉的股价一直高于其他两支股票,这个问题的答案不是单由股价决定,我们还需要考虑公司的总市值,尽管我们目前的数据并没有关于目前股票总单位的信息,但是,我们可以做一个简单的计算,在这里我们假设总的交易金额将是成交量列乘以开盘价格,这只是对市值的粗略估计而不是真实的市场价值,我们只是使用时间序列来直观地表示交易的总金额

为每个dataframe 创建一个名为总交易量新的一列,及开盘价格与成交量的乘积

第三部分,通过计算和比较每日收益来进行基本财务分析,并绘制每只股票的每日收益分布图来识别三者之间的关系

每日百分比可以通过下面的公式计算所得

从收盘价 列计算收益

同时我们用一些box plot 来比较三只股票的收益范围

比较股票的日收益

我们绘制散点矩阵图,以查看每个股票日收益率之间的相关性

从上面的scatter 矩阵图 ,我们可以看出只有通用和特斯拉汇报率关系图和其他4对关系图看起来不一样,所以我们可以推断特斯拉和通用确实有某种关系

累积日收益

日收益 是指股票价格相对于前一日的损益

累积回报 累积回报是相对于投资计算的,如果累计回报超过一,你就是在盈利,否则就是亏损

累积日收益的公式为

df[daily_cumulative_return] = ( 1+df[pct_daily_return] ).cumprod()

假设我们从2012年1月3日开始买入这三支股票并一直持有,则我们的累积日均收益为

下面我们来可视化一下三支股票的累计收益率,可以发现购入特斯拉后,它的价格涨了14倍

使用python实时监控股票,并且持续扫描大盘

使用python 实现监控股票并持续扫描大盘,可以通过以下步骤来完成

  1. 安装必要的库,需要安装 pandas numpy requests matplotlib 等库,可以通过pip 命令进行安装

获取数据 可以通过python来获取股票实时数据和历史数据

可以使用pandas 库来处理数据

数据分析,可以通过pandas 和numpy 库来进行数据分析,可以进行技术分析,例如移动平均线 MACD RSI 等,也可以进行基本面分析,例如 市盈率 市净率 ROE 等

可视化 可以使用matplotlib 库来可视化数据,例如 绘制K线图,交易量图,技术指标图等

持续扫描,可以使用python 的time 或schedule 模块来进行定时任务,例如每隔10秒钟获取一次股票数据

20230402-几款不错的RPA开源软件分享RPAPlus

智能自动化将成为大势所趋,但并不是所有公司都选择购买商业付费软件,有部分研发能力较强的公司可能会采取自研或结合开源框架的手段

Robot Framework
是目前比较活跃的开源项目之一,是测试自动化和RPA 的通用框架,与其他语言一样,它强调自然语言或人类可读的语言,以使其更易于使用

Robot Framework 还提供了一个web 演示和完整的文档

RPAPlus 实际试用后觉得这个框架可能更偏向于自动化测试

TagUI

由AI singapore 维护,是一个用于RPA 的命令行界面,可以在任何主要的操作系统上运行,这是开源 RPA 工具的一个常见特性,也是它与一些商业工具的区别之一,TagUi 使用术语和相关的流程概念来表示运行一个基于计算机的自动化流程,该流程可以按需完成,也可以按固定的时间表完成,

tagui 强调其语言的简单或自然,贡献者 ken soh 在2017年 发布的一篇介绍tagui 的媒体文章中写道, 这使得ui 自动化的快速原型化 部署和维护变得容易,无论你是否是开发人员,tagui 有丰富的在线文档

tagui 的界面是纯命令行

RPA for python

以前叫做 tagui for python 这是一个用于rpa 开发的python包,rpa for python 是在tagui 上构建的,因此有了最初的名字,它拥有网站自动化,计算机视觉自动化,光学字符识别和键盘鼠标自动化等基本功能

python 中 pip install rpa即可安装

openRPA

openrpa 也是一个蛮有趣的项目,基于windows workflow foundation 作为框架,wf 被uipath 和许多国内rpa 团队应用

Github: https://github.com/open-rpa/openrpa

remark 谈到 windowsWF 曾经我们基于WF的框架Demo 用很短的时间就可以做一个rpa的studio 原型出来,说明技术含量是不高的,请参考此文 含视频

Robocorp

Robocorp 是早期初创公司,该公司去年获得了560万美元的种子轮融资,承诺为开发人员提供基于云的开源RPA工具,官网目前可以通过邮件申请早期账户

Automagica

这可能是开源模式和免费增值模式之间的分界线 automagic 确实是开源的,对于非商业用途是免费的,但是商业用途需要商业许可证,这使得它成为希望学习、试验进而原型的个人的一个潜在的好选择,但是商业用例将需要迁移到它的商业 automagica 门户平,automagica 也有相对全面的介绍文档

automagica的自动化能力实现是基于python,独立开发了一个云端应用平台,可以实现网页端的编码

Github: https://github.com/automagica/automagica

Taskt 强调易用性和无代码或低代码,Taskt 是一个免费的开源工具,它承诺了同样的功能,无需编写代码就可以自动执行任务,它的功能之一是屏幕记录器,记录用户基于计算机的操作,然后将这些步骤转换成可重复的脚本,RPA bot 它还包括一个 看到什么就得到什么 的bot 设计器,其中包含一个用于无代码RPA 开发的标准命令菜单

Github: https://github.com/saucepleez/taskt

  • Copyrights © 2015-2024 TeX_baitu
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~