版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
太原理工大学毕业设计(论文)用纸 太原理工大学毕业设计(论文)任务书第1页毕业设计(论文)题目:Linux环境下电子阅读器的设计与实现毕业设计(论文)要求及原始数据(资料):1.查看并了解电子阅读器的编码和解码;2.深入了解专用电子阅读器文件格式的解读以及转码;3.熟练掌握电子阅读器阅读器的设计原理,训练编写程序的能力;4.学会在Linux环境下应用qt编程,开发;5.深入分析电子阅读器编码解码的关键技术与语言;6.训练检索文献资料和利用文献资料的能力;7.训练撰写技术文档与学位论文的能力。第2页毕业设计(论文)主要内容:1.综述电子阅读器在日常生活和社交层面的应用;2.了解设计电子阅读器的相关技术;3.熟悉了解电子阅读器的qt开发环境;4.深入分析电子阅读器的关键技术与程序设计流程;5.熟练掌握电子阅读器的制作和测试;学生应交出的设计文件(论文):1.内容完整、层次清晰、叙述流畅、排版规范的毕业设计论文;2.包括毕业设计论文、源程序等内容在内的毕业设计电子文档及其它相关材料。第3页主要参考文献(资料):相洁.软件开发环境与工具.太原理工大学出版社,2012庞丽萍,郑然.操作系统原理与linux系统实验.机械工业出版社,2011严蔚敏.数据结构.清华大学出版社,2002陈洁.Linux窗口程序设计—Qt4精彩实例分析.清华大学,2008宫虎波.Linux编程从入门到精通.化学工业出版社,2009KennethaReek.PointersOnC[M].ADDISONWESLEYPublishingCompanyIncorporated,1998AndrewKoenig.CTrapandPitfalls[M].PearsonEducation,1989JasminBlanchett,MarkSummerfield.C.plus.plus.GUI.Programming.with.Qt.4[M].PrenticeHall,2008RobertLove.LinuxKernelDevelopment[M].PearsonEducation,2010W.RichardStevens,StephenA.Rago.AdvancedProgrammingintheUNIXEnvironment.PrenticeHall,1998专业班级软件1010班学生要求设计(论文)工作起止日期2014年3月17日~2014年6月10日指导教师签字日期2014年3月17日教研室主任审查签字日期系主任批准签字日期引言说到本项目我们需要简单了解以下技术背景。嵌入式Linux是以Linux为基础的嵌入式作业系统,它被广泛应用在移动电话、个人数字助理(PDA)、媒体播放器、消费性电子产品以及航空航天等领域中。它的目的是将日益流行的Linux操作系统进行裁剪修改,使之能在嵌入式计算机系统上运行的一种操作系统。嵌入式linux既继承了Internet上无限的开放源代码资源,又具有嵌入式操作系统的特性。嵌入式Linux的特点是版权费免费;购买费用媒介成本技术支持全世界的自由软件开发者提供支持网络特性免费,而且性能优异,软件移植容易,代码开放,有许多应用软件支持,应用产品开发周期短,新产品上市迅速,因为有许多公开的代码可以参考和移植,实时性能RT_LinuxHardhatLinux等嵌入式Linux支持,实时性能稳定性好安全性好。而作为计算机发展最迅速的领域之一的嵌入式技术,已经形成了一整套独有的理论,并广泛地应用于人们的生产和生活中。但是,为了将这样的技术进行教学普及以便于社会生产和使用,于是就诞生了其逆向技术——虚拟机技术。虚拟机(VirtualMachine)指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机软件或系统,而虚拟机技术,顾名思义,就是将特有硬件功能以某种特定而对应的软件环境中得到实现,并非在硬件本身里面实现的过程。它作为嵌入式技术的子技术以及逆向技术是当今嵌入式发展的不可或缺的技术。有了它,我们可以方便地了解使用及开发那些独占平台文件,甚至可以做到反技术垄断。因此,作为嵌入式软件开发者,虚拟机技术是很广泛的,但是同时又是很严苛的,掌握它既是一项艰巨的任务,又是一项必不可少的个人技术提升之路。虚拟机技术的特点在于:低成本甚至完全免费。不需要购买对应的硬件来实现,只需要安装一个模拟器即可实现专用平台的功能便于教学和技术扩展研究。在对应平台上你对专用文件格式只具有读取权限,不具有写权限以及执行权限,这给开发人员造成非常不必要的麻烦。也让技术的发展和提升被严重限制。而对应的虚拟机诞生之后,工作以及研发人员就可以对其进行改造和升级。可维护性大大提高。如果你读取专有格式文件的硬件出现问题,作为使用者你几乎无法维修硬件,这个时候你就需要这样一个虚拟软件环境能够帮助你读取对应格式文件,而如果这个软件出现问题,你可以卸载并重新安装随着信息时代的来临,很多垄断技术和文件均被分享,但是仍然有一些公司仗着平台文件大肆垄断,同时,也有很多平台文件我们普通PC无法读取,这不仅造成资源得不到共享,垄断中的技术得不到更新,同时造成一家独大的局面。要打破这种局面,虚拟机技术就是王牌,但是熟练掌握到运用自如这是一段艰难的路。另外,用惯了windows的大家都知道,windows上面的软件总数要远远大于Linux的软件总数,这使得很多能够在windows下面运行的软件放到Linux下面就形成了空缺,甚至都没有专门的项目。就如本作者编写的这个虚拟机程序,它对应的UMD只在windows下面有专门的软件,而且同样是官方程序加载非官方插件的版本,而非独立软件版本,这使得对于开发者和阅读人员造成了许多程序上的麻烦之处。所以,本作者所做的就是解决平台独占中其中的某一项:诺基亚手机专用文档UMD格式的文件在PC端特别是LINUX系统环境下运行,并实现PDF,PS文件以及可写文件TXT的转码。当然,为了防止文件修改所带来的版权纠纷,我刻意去掉了编辑功能,另软件只有读取功能而没有写功能,只有大家转码成txt,才具有可写功能,希望大家谅解。本作者是一个学生党,在这方面的技术有待于提高,如果大家使用过程中有问题,尽可以提供宝贵意见,我们将衷心致力于软件的改进。2环境工具介绍2.1Linux系统介绍 本软件编译,运行在Linux操作系统环境下,这里我选用了库函数非常齐全的Ubuntukylin14.04版本。 首先来说一下Ubuntu:Ubuntu(乌班图)是一个以桌面应用为主的Linux操作系统,其名称来自非洲南部祖鲁语或豪萨语的“ubuntu”一词,意思是“人性”、“我的存在是因为大家的存在”,是非洲传统的一种价值观,类似华人社会的“仁爱”思想。Ubuntu基于Debian发行版和GNOME桌面环境,与Debian的不同在于它每6个月会发布一个新版本。Ubuntu的目标在于为一般用户提供一个最新的、同时又相当稳定的主要由自由软件构建而成的操作系统。Ubuntu具有庞大的社区力量,用户可以方便地从社区获得帮助。2013年1月3日,Ubuntu正式发布面向智能手机的移动操作系统。Ubuntu是基于DebianGNU/Linux,支持x86、amd64(即x64)和ppc架构,由全球化的专业开发团队(CanonicalLtd)打造的开源GNU/Linux操作系统。为桌面虚拟化提供支持平台。Ubuntu对GNU/Linux的普及特别是桌面普及作出了巨大贡献,由此使更多人共享开源的成果与精彩。Ubuntu是一个南非的民族观念,该词来自于祖鲁语和科萨语,意为人们之间的忠诚和联系。被视为非洲人的传统理念,也是建立新南非共和国的基本原则之一,与非洲复兴的理想密切相关。Ubuntu精神的大意是“人道待人”。另一种翻译可以是:“天下共享的信念,连接起每个人”。具有Ubuntu精神的人心胸开阔,乐于助人,见贤思齐而不忌妒贤能,因为他/她拥有适度的自信。而这源自如下认识:“自己乃是属于一个更大的整体,当他人受到伤害或死去时,当他人受到折磨或压迫时,这个整体就会消失。”——大主教DesmondTutu。 下面是Ubuntukylin14.04简介。 2014年4月22日,由工业和信息化部软件与集成电路促进中心(CSIP)携手国防科技大学(NUDT)和Canonical公司合作成立的CCN开源软件创新联合实验室在北京召开新产品发布会,宣布UbuntuKylin14.04LTS版本正式发布并确定中文名为“优麒麟”。UbuntuKylin14.04LTS是UbuntuKylin操作系统的第三个正式发行版,也是首个长期支持(LTS)版,提供了最新的功能和工具,以确保直观而舒适的用户体验。UbuntuKylin14.04版本主要特性有:内核采用LinuxKernel3.13.0,相对于Ubuntu12.04所采用内核,3.13版本内核在网络、调度、电源管理、虚拟化、文件系统、安全以及硬件支持等方面均有大幅改进;搭载UbuntuKylin软件中心:支持Ubuntu和UbuntuKylin软件仓库;中文化方面,与UbuntuLocoTeam社区合作,对主要软件界面、软件中心描述以及系统帮助文档进行了全面中文化工作;系统桌面主题定制:提供了定制的开机动画和从壁纸大赛中挑选的系统壁纸,也默认搭载了定制的系统主题UbuntuKylin。系统应用方面:——默认搭载优客助手,可为UbuntuKylin用户提供系统管理和配置工具;——基于小企鹅输入法框架定制推出搜狗输入法的Linux版本,并为输入法定制开发了操作面板;——默认安装了UbuntuKylin团队与金山联合开发的Linux版本金山网盘客户端;——提供了WPSforLinux版本办公套件。与此同时,UbuntuKylin14.04LTS版本还针对最新的台式计算机和笔记本电脑以及多种触控设备,如触控板和触摸屏、高像素密度(DPI)屏幕键盘和鼠标等,进行了优化。UbuntuKylin13.10用户如果要升级到UbuntuKylin14.04的话,可按下快捷键Alt+F2,输入“updatemanager”,在弹出的更新管理器窗口中选择可用的UbuntuKylin14.04LTS版本并按照屏幕提示升级即可。2.2QTcreator环境介绍QtCreator是跨平台的QtIDE,QtCreator是Qt被Nokia收购后推出的一款新的轻量级集成开发环境(IDE)。此IDE能够跨平台运行,支持的系统包括Linux(32位及64位)、MacOSX以及Windows。根据官方描述,QtCreator的设计目标是使开发人员能够利用Qt这个应用程序框架更加快速及轻易的完成开发任务。 QtCreator包括项目生成向导、高级的C++代码编辑器、浏览文件及类的工具、集成了QtDesigner、QtAssistant、QtLinguist、图形化的GDB调试前端,集成qmake构建工具等。 QtCreator主要是为了帮助新Qt用户更快速入门并运行项目,还可提高有经验的Qt开发人员的工作效率。 特点:使用强大的C++代码编辑器可快速编写代码语法标识和代码完成功能输入时进行静态代码检验以及提示样式上下文相关的帮助代码折叠括号匹配和括号选择模式高级编辑功能。使用浏览工具管理源代码。集成了领先的版本控制软件,包括Git、Perforce和Subversion开放式文件,无须知晓确切的名称或位置搜索类和文件跨不同位置或文件沿用符号在头文件和源文件,或在声明和定义之间切换为Qt跨平台开发人员的需求而量身定制。集成了特定于Qt的功能,如信号与槽(Signals&Slots)图示调试器,对Qt类结构可一目了然集成了QtDesigner可视化布局和格式构建器只需单击一下就可生成和运行Qt项目。这里面用到的底层语言是C语言,编译工具是Linux操作系统下主流软件gcc控制台以及类库,具体介绍一下类似windows下的vs2010的编程软件QTcreator而qt本身则是一个1991年由奇趣科技开发的跨平台C++图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(MetaObjectCompiler,moc))以及一些宏,易于扩展,允许组件编程。2008年,奇趣科技被诺基亚公司收购,QT也因此成为诺基亚旗下的编程语言工具。2012年,Qt被Digia收购。2014年4月,跨平台集成开发环境QtCreator3.1.0正式发布,实现了对于iOS的完全支持,新增WinRT、Beautifier等插件,废弃了无Python接口的GDB调试支持,集成了基于Clang的C/C++代码模块,并对Android支持做出了调整,至此实现了全面支持iOS、Android、WP。Qt因为4.x版本和5.x版本其类库有较大的变动,这里,我们采用旧版的qt即qt4.8.6进行编写。如图2所示的QTcreator使用范例。图2qt使用范例2.3GCC编译环境介绍 GCC(GNUCompilerCollection,GNU编译器套装)是一套由GNU工程开发的支持多种编程语言的编译器。GCC是自由软件发展过程中的著名例子,由自由软件基金会以GPL协议发布。GCC是大多数类Unix操作系统(如Linux、BSD、MacOSX等)的标准的编译器,GCC同样适用于微软的Windows。GCC支持多种计算机体系芯片,如x86、ARM,并已移植到其他多种硬件平台。GCC原名为GNUC编译器(GNUCCompiler),因为它原本只能处理C语言。GCC很快地扩展,并支持处理C++。后来又扩展能够支持更多编程语言,如Fortran、Pascal、Objective-C、Java、Ada、Go等。 GCC(GNUCompilerCollection,GNU编译器套装),是由GNU开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是GNU计划的关键部分。GCC原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(如Linux、BSD、MacOSX等)采纳为标准的编译器,GCC同样适用于微软的Windows。GCC是自由软件过程发展中的著名例子,由自由软件基金会以GPL协议发布。GCC原名为GNUC语言编译器(GNUCCompiler),因为它原本只能处理C语言。GCC很快地扩展,变得可处理C++。之后也变得可处理Fortran、Pascal、Objective-C、Java,以及Ada与其他语言。 关于他的结构: GCC的外部接口长得像一个标准的Unix编译器。使用者在命令列下键入gcc之程序名,以及一些命令参数,以便决定每个输入档案使用的个别语言编译器,并为输出程序码使用适合此硬件平台的组合语言编译器,并且选择性地执行连结器以制造可执行的程序。每个语言编译器都是独立程序,此程序可处理输入的原始码,并输出组合语言码。全部的语言编译器都拥有共通的中介架构:一个前端解析符合此语言的原始码,并产生一抽象语法树,以及一翻译此语法树成为GCC的暂存器转换语言〈RTL〉的后端。编译器最佳化与静态程序码解析技术(例如FORTIFY_SOURCE,一个试图发现缓冲区溢位〈bufferoverflow〉的编译器)在此阶段应用于程序码上。最后,适用于此硬件架构的组合语言程序码以JackDavidson与ChrisFraser发明的算法产出。2.3.1前端接口 前端的功能在于产生一个可让后端处理之语法树。此语法解析器是手写之递回语法解析器。直到最近,程序的语法树结构尚无法与欲产出的处理器架构脱钩。而语法树的规则有时在不同的语言前端也不一样,有些前端会提供它们特别的语法树规则。在2005年,两种与语言脱钩的新型态语法树纳入GCC中。它们称为GENERIC与GIMPLE。语法解析变成产生与语言相关的暂时语法树,再将它们转成GENERIC。之后再使用"gimplifier"技术降低GENERIC的复杂结构,成为一较简单的静态唯一形式(StaticSingleAssignmentform,SSA)基础的GIMPLE形式。此形式是一个与语言和处理器架构脱钩的全域最佳化通用语言,适用于大多数的现代编程语言。2.3.2中介接口 一般编译器作者会将语法树的最佳化放在前端,但其实此步骤并不看语言的种类而有不同,且不需要用到语法解析器。因此GCC作者们将此步骤归入通称为中介阶段的部分里。此类的最佳化包括消解死码、消解重复运算与全域数值重编码等。许多最佳化技巧也正在实作中。2.3.3后端接口 GCC后端的行为因不同的前处理器宏和特定架构的功能而不同,例如不同的字符尺寸、呼叫方式与大小尾序等。后端接口的前半部利用这些讯息决定其RTL的生成形式,因此虽然GCC的RTL理论上不受处理器影响,但在此阶段其抽象指令已被转换成目标架构的格式。GCC的最佳化技巧依其释出版本而有很大不同,但都包含了标准的最佳化算法,例如循环最佳化、执行绪跳跃、共通程序子句消减、指令排程等等。而RTL的最佳化由于可用的情形较少,且缺乏较高阶的资讯,因此比较起近来增加的GIMPLE语法树形式,便显得比较不重要。后端经由一重读取步骤后,利用描述目标处理器的指令集时所取得的资讯,将抽象暂存器替换成处理器的真实暂存器。此阶段非常复杂,因为它必须关照所有GCC可移植平台的处理器指令集的规格与技术细节。后端的最后步骤相当公式化,仅仅将前一阶段得到的组合语言码藉由简单的副函式转换其暂存器与内存位置成相对应的机械码。2.3.4基本用法 在使用Gcc编译器的时候,我们必须给出一系列必要的调用参数和文件名称。GCC编译器的调用参数大约有100多个,其中多数参数我们可能根本就用不到,这里只介绍其中最基本、最常用的参数。GCC最基本的用法是∶gcc[options][filenames]其中options就是编译器所需要的参数,filenames给出相关的文件名称。-c,只编译,不链接成为可执行文件,编译器只是由输入的.c等源代码文件生成.o为后缀的目标文件,通常用于编译不包含主程序的子程序文件。-ooutput_filename,确定输出文件的名称为output_filename,同时这个名称不能和源文件同名。如果不给出这个选项,gcc就给出预设的可执行文件a.out。-g,产生符号调试工具(GNU的gdb)所必要的符号资讯,要想对源代码进行调试,我们就必须加入这个选项。-O,对程序进行优化编译、链接,采用这个选项,整个源代码会在编译、链接过程中进行优化处理,这样产生的可执行文件的执行效率可以提高,但是,编译、链接的速度就相应地要慢一些。-O2,比-O更好的优化编译、链接,当然整个编译、链接过程会更慢。-Idirname,将dirname所指出的目录加入到程序头文件目录列表中,是在预编译过程中使用的参数。C程序中的头文件包含两种情况∶A)#include<myinc.h>B)#include“myinc.h”其中,A类使用尖括号(<>),B类使用双引号(“”)。对于A类,预处理程序cpp在系统预设包含文件目录(如/usr/include)中搜寻相应的文件,而B类,预处理程序在目标文件的文件夹内搜索相应文件。2.4文件架构依赖包的使用简介2.4.1zlib的简介以及作用zlib是提供数据压缩用的函式库,由Jean-loupGailly与MarkAdler所开发,初版0.9版在1995年5月1日发表。zlib使用DEFLATE算法,最初是为libpng函式库所写的,后来普遍为许多软件所使用。此函式库为自由软件,使用zlib授权。截至2007年3月,zlib是包含在Coverity的美国国土安全部赞助者选择继续审查的开源项目。Zlib具有以下特性:数据头(header)zlib能使用一个gzip数据头,zlib数据头或者不使用数据头压缩数据。通常情况下,数据压缩使用zlib数据头,因为这提供错误数据检测。当数据不使用数据头写入时,结果是没有任何错误检测的原始DEFLATE数据,那么解压缩软件的调用者不知道压缩数据在什么地方结束。gzip数据头比zlib数据头要大,因为它保存了文件名和其他文件系统信息,事实上这是广泛使用的gzip文件的数据头格式。注意zlib函式库本身不能创建一个gzip文件,但是它相当轻松的通过把压缩数据写入到一个有gzip文件头的文件中。算法目前zlib仅支持一个LZ77的变种算法,DEFLATE的算法。这个算法使用很少的系统资源,对各种数据提供很好的压缩效果。这也是在ZIP档案中无一例外的使用这个算法。(尽管zip文件格式也支持几种其他的算法)。看起来zlib格式将不会被扩展使用任何其他算法,尽管数据头可以有这种可能性。使用资源函数库提供了对处理器和内存使用控制的能力,不同的压缩级别数值可以指示不同的压缩执行速度。还有内存控制管理的功能。这在一些诸如嵌入式系统这样内存有限制的环境中是有用的。策略压缩可以针对特定类型的数据进行优化。如果你总是使用zlib库压缩压缩特定类型的数据,那么可以使用有针对性的策略可以提高压缩效率和性能。例如,如果你的数据包含很长的重复数据,那么可以用RLE(运行长度编码)策略,可能会有更好的结果。对于一般的数据,默认的策略是首选。错误处理错误可以被发现和跳过数据混乱可以被检测(只要数据和zlib或者gzip数据头一起被写入-参见上面)此外,如果全刷新点(full-flushpoints)被写入到压缩后的数据流中,那么错误数据是可以被跳过的,并且解压缩将重新同步到下个全刷新点。(错误数据的无错恢复被提供)。全刷新点技术对于在不可靠的通道上的大数据流是很有用的,一些过去的数据丢失是不重要的,但是建立太多的全刷新点会极大的影响速度和压缩。数据长度对于压缩和解压缩,没有数据长度的限制。重复调用库函数允许处理无限的数据块。一些辅助代码(计数变量)可能会溢出,但是不影响实际的压缩和解压缩。当压缩一个长(无限)数据流时,最好写入全刷新点。2.4.2qmake介绍以及特点qmake是一个协助简化跨平台进行专案开发的构建过程的工具程式,Qt附带的工具之一。qmake能够自动生成Makefile、MicrosoftVisualStudio
专案文件和xcode专案文件。不管源代码是否是用Qt写的,都能使用qmake,因此qmake能用于很多软件的构建过程。[1]特点:手写Makefile是比较困难而且容易出错,尤其在进行跨平台开发时必须针对不同平台分别撰写Makefile,会增加跨平台开发复杂性与困难度。qmake会根据专案文件(.pro)里面的信息自动生成适合平台的Makefile。开发者能够自行撰写专案文件或是由qmake本身产生。qmake包含额外的功能来方便Qt开发,如自动的包含moc和uic的编译规则。3系统分析3.1格式介绍3.1.1PC格式EXE不需要安装专门的阅读器,下载后就可以直接打开。单击目录可直接打开所需内容。TXT它在电脑上是记事本的扩展名,这种现在普遍应该到电子产品中,现在最常见的就是TXT小说,不仅方便的在电脑上打开,还可以下载到的MP3和手机中,现在网上TXT小说网站也很多,比如著名的飘零书社就是专业的TXT格式小说下载网站,可以很方便的下载自己的手机或MP3中,省去很多购买书的费用;HTML网页格式,可用网页浏览器直接打开;HLP帮助文件格式,在Windows上可直接打开;一般在程序中按F1可以打开。CHM同HLP文件格式一样,也是帮助文件,但其支持多种视音频格式,让电子书显得更加生动美观。LIT微软的文件格式,需下载MicrosoftReader软件来阅读。PDFPDF是ADOBE公司开发的电子读物文件格式,是目前使用最普及的电子书格式,它可以真实地反映出原文档中的格式、字体、版式和图片,并能确保文档打印出来的效果不失真。WDL这是北京华康公司的文件格式,使用也很普遍。用DynaDoc免费阅读软件即可打开WDL和WDF格式。CEB此格式是由北大方正公司独立开发的电子书格式,由于在文档转换过程中采用了“高保真”技术,从而可以使CEB格式的电子书最大限度地保持原来的样式。ABM一种全新的数码出版物格式,这种格式最大的优点就是能把文字内容与图片、音频甚至是视频动画结合为一个有机的整体。在阅读时,能带来视觉、听觉全方位享受。PDG超星公司把书籍经过扫描后存储为PDG数字格式,存放在超星数字图书馆中。如果你要想阅读这些图书,则必须使用超星阅览器(SuperstarReader)。EPUBEPUB是可重排版(reflowable直译可回流)的基于XML格式的电子书或其它数字出版物,是数字出版业商业和标准协会InternationalDigitalPublishingForum(IDPF)制定的标准。有各种开放源代码或者商业的阅读软件支持几乎所有的主流操作系统。CAJCAJ为中国学术期刊全文数据库英文缩写(ChinaAcademicJournals);CAJ是中国学术期刊全文数据库中文件的一种格式。可以使用CAJ全文浏览器来阅读。3.1.2手机格式UMD该格式原先为诺基亚手机操作系统支持的一种电子书的格式,阅读该格式的电子书需要在手机上安装相关的软件。不过现在的很多java手机下载阅读软件后也可以看。JARJAR文件格式以流行的ZIP文件格式为基础。与ZIP文件不同的是,JAR文件不仅用于压缩和发布,而且还用于部署和封装库、组件和插件程序,并可被像编译器和JVM这样的工具直接使用。3.2技术需求分析3.2.1UMD格式解码技术 使用这项技术之前我们先来了解一下UMD文件格式:UMD文件有三种格式类型,一种叫纯文本格式,一种叫漫画&写真集格式,以及连环画(文字+图画)。本文只涉及纯文本格式的UMD,后面将直接使用UMD指代这类格式的文件。
UMD文件总体上是由一组连续的块组成的,每一块按照约定的顺序先后排列在一起构成了UMD文件的结构。根据块的职责,我将其分成两类:功能块和数据块。有的功能块自身就可以完全的描述信息,而有的一些由于信息量大,特别地将数据放在别处(即数据块),如正文、章节偏移和章节标题,它们使用一个功能块和若干个数据块,通常数据块都紧接在相应的功能块之后出现。如表3-1所示的解码代码块的原理。表3-1UMD块标识块标识描述参数定义0x01UMD文件头DCTS_CMD_ID_VERSION0x02文件标题DCTS_CMD_ID_VERSION0x03作者DCTS_CMD_ID_VERSION0x04年DCTS_CMD_ID_VERSION0x05月DCTS_CMD_ID_VERSION0x06日DCTS_CMD_ID_VERSION0x07小说类型DCTS_CMD_ID_VERSION0x08出版商DCTS_CMD_ID_VERSION0x09零售商DCTS_CMD_ID_VERSION表3-1(续)块标识描述参数定义0x0B内容长度DCTS_CMD_ID_VERSION0x0C文件结束DCTS_CMD_ID_VERSION0x81正文DCTS_CMD_ID_VERSION0x82封面DCTS_CMD_ID_VERSION0x83章节偏移DCTS_CMD_ID_VERSION0x84章节标题正文DCTS_CMD_ID_VERSION0x87页面偏移DCTS_CMD_ID_VERSION0x0AContentIDDCTS_CMD_ID_VERSION0xF0CDSKEYDCTS_CMD_ID_VERSION0xF1许可证DCTS_CMD_ID_VERSION0x05月DCTS_CMD_ID_VERSION以上数据块标识中,在本程序中我们仅用到8个左右。如表3-2所示的功能块结构以及表3-3所示的数据块结构。表3-2UMD功能块结构格式大小描述#1这是一个功能块0x23category2见表1unknown1未知Length1功能块长度contentn功能块的内容。一般是字符型的数据,并且以UNICODE编码存储,不带字符串结尾符0。Content所占用的字节数加上前面各字段的大小(前面共有5字节)即为Length。如果此功能块后接一个数据块的话,Content存放的不是实际的内容,而是一个4字节的数,它引用着一个数据块,该数据块头部也会包含同样的4个字节来标识自己。表3-3UMD数据块结构格式大小描述$1数据块0x24Randval4一个数据块标识,与对应功能块中的Content相同。注意正文数据块有所不同,后面将提到。Length4整个数据块的长度(字节数)contentn实际的数据,一般都很大。如正文的内容实际上划分为了很多块,分别放入了不同的数据块中。如上表3-3所示,功能块与数据块都有着各自的格式,UMD中的块都遵循这两种格式之一。尽管大体上简单明了,由于Content中实际存储的数据不同,其Content中的结构也有所不同。3.2.2C语言开发依据以及执行过程通过表3-1到表3-3我们不难得出,这里的C语言开发主要是进行系统编程的接口和解压缩编程,并且需要用到ZLIB压缩与解压缩函数类包虽然我们称Gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤∶预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和链接(Linking)。命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。接着调用cc1进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.S为后缀的汇编语言源代码文件和汇编、.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当的位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。3.3可行性分析从“格式介绍”一栏中我们看出UMD原先为诺基亚手机开发,现在虽然有Java等程序,但是绝大多数是windows下面的,这是一方面,另一方面,UMD编程非常简单,只要掌握了其数据结构,就不难对其进行设计和开发,我认为此项目的特色以及针对性很强,可行性很高,值得重视并执行,总体来讲,这个项目具有经济可行性,操作可行性,技术可行性。4概要设计4.1总体功能实现UMD的浏览,归档功能,PDF,PS格式转码,可写文件txt另存为功能鉴于以上对UMD文件的软件支持甚少,我们对此作出如下目的性分析,即本系统需要具有以下功能:(1)拥有简单干净易上手的操作界面(2)能够实现文件路径的打开关闭功能。(3)能够实现UMD文件浏览,章节归类,书签管理功能(4)能够实现转码打印功能(5)能够实现PDF,PS转码打印和另存为txt可写文件功能。4.2功能展示以及UI界面描述 由于这套软件属于功能集成类型的软件,而非系统类型,功能之间不需要复杂的等级划分,层级结构比较单一,只有两层,打开和关闭是最上层,而文件的浏览,转码,文档章节的归类以及放大缩小等功能属于第二层。所以这里只列出功能规划图以及UI界面的设计范例,不做详细的规划,只需要简单的集成即可。打开打开兼浏览UMD文档,章节自动归档书签管理书签管理放缩查找查找查看查看转码成为转码成为其他格式的文件如ps,txt,PDF图4-1功能规划图 由图4-1我们知道,这六种功能之间的制约关系非常小,耦合度低。因而是功能集成的类型。(而我们众所周知的“某某管理系统”“某某网站”这类型的项目,其功能间制约关系非常严重,进而等级划分要求非常之高,所以是系统类型)图4-2功能的UI界面设计 由图4-2我们可以得知,界面中包含标题栏,菜单栏,工具栏,书目栏,章节列表,书签管理表(位于章节列表垂直下方),标题栏是我的名称,菜单栏包括“文件,编辑,查看,帮助”选项。工具栏包括“打开,另存为,打印,查找,放大,缩小”功能,其中,另存为和打印的作用实质即是转码。4.3代码框架以及程序总流程4.3.1代码框架图4-3代码全局图如图4-3的代码全局图。Aboutdialog是程序介绍以及编写的作者,UmdReader是文档大小计算,字体初始化等基础设置。Main.cpp是文件运行环境以及安装包封装。资源里面包含了按钮的样式,这里不做详细介绍。最主要的3个是addition,mainwindow以及bookmarket。下面在“5详细设计以及实现”会详细介绍。4.3.2程序总流程开始开始动作动作否否是否是否响应成功是是响应后的互动操作,响应后的互动操作,并执行对应一个或多个功能提示无法执行对应功能结束结束图4-4总体编程思想如图4-4所示,这即是程序总体流程设计图,又是编程思想的框架图。在正式详细介绍代码和对应的实现之前,首先我在这里介绍我对功能实现的编程框架,即是:动作——响应触发——响应后的互动操作。任何功能的实现,即不能离开又不会偏离这个框架。先来介绍动作部分,这里的“动作”是指你用输入设备对程序作出一项操作指令,这个过程称之为动作。举个例子,你用鼠标点击软件的某项功能按钮,这个过程即是动作的一种。或者你用键盘输入字符到程序中,也是一个动作。这个动作在QT里面是用QAction类实现,这个类的作用就是用于负责将你的动作转换成信号发送给程序端。这个部分是功能的介绍,属于静态部分,因此可以用图片进行简介。之后介绍响应部分,响应,顾名思义就是接受对方的操作指令信息,但是整个过程的实质是响应一方和被响应一方之间的指令信息连接。若连接异常,响应一方因为无法接受指令,是无法进行后续互动操作的。即响应的作用就是动作和互动操作之间的桥梁。用connect方法进行实现。最关键的是,操作的触发过程是动态过程只能用实机演示证明,因此无法用图片进行介绍。最后介绍响应后的互动操作部分,这个互动操作的意思就是你用输入设备对程序作出一项操作指令,程序响应你的指令后,对你的要求进行执行的操作。举个例子,你用鼠标点击了放大功能,程序响应你的指令之后,对文档进行放大操作。这个互动操作实质跟你的设计界面相关,即是对你界面上的按钮等功能模块的设计和实现,具体的类与接口没有严格定义,但需要自己设计和实现。本操作属于伴随操作,也就是说整个过程的性质是动态且被动的,因此只能用实机演示,无法用图片介绍。本代码除了书签功能要用到bookmarketwidget.cpp之外,其余功能均包含在文件MainWindow.cpp代码中。5详细设计以及实现5.1后台设计在源代码中所用到的总后台,用于变量定义,所有方法定义,分别定义在addition.h以及umdparser.h里面,并对应着相应的cpp源文件,前者定义了UMD对象的属性(根据前面提到的块标识),后者定义了读取以及释放的操作5.1.1UMD命名空间在下面名为addition的头文件代码中,我们不难发现,所有的定义,均围绕UMD块标识而进行。这是UMD解读程序编写的根本,它的作用类似于数学里面的定力定义的作用,是规范以及编写规则的代码实现。Addition.h:#ifndefADDITIONS_H#defineADDITIONS_H#include<stdio.h>#include<stdlib.h>#include<string.h>namespaceUMD //在addition.h里面对UMD进行功能定义{intWideCharToMultiByte(char*des,unsignedchar*sr,unsignedlongin_byte,unsignedlongout_byte); //对属性值“路径,源文件”等进行字符转换voidEnterFilter(unsignedchar*p,unsignedintlen);structHead //用队列指针头部对书籍的属性进行总定义{enumAttribute //对书籍的属性进行枚举定义,定义中包含8项块标识{Title=0,Author,Year,Month,Day,Gender,Publisher,Vendor};Head();Head(Head&other);~Head(); //对头部属性数据进行释放unsignedchar*title;unsignedchar*author;unsignedchar*year;unsignedchar*month;unsignedchar*day;unsignedchar*gender;unsignedchar*publisher;unsignedchar*vendor;voidsetAttribute(Attributea,unsignedchar*atr,intlen);}; //设置属性值到属性按钮中structChapter //章节的定义{Chapter(char*t,int_len,unsignedint_offset);Chapter(Chapter&other);~Chapter(); //同样进行章节的释放,包括题目char*title; //题目定义unsignedintoffset;};structCover//对书籍的封面进行定义{enumTYPE //这里对用到的图片资源进行统一的枚举归类{bmp=0,jpg,gif}type;Cover(TYPEt,unsignedchar*img,unsignedintlen);//对封面进行加载Cover(Cover&other);~Cover(); //释放封面资源unsignedchar*content;unsignedintlength;};structContent//书籍目录的定义{Content(unsignedchar*d,unsignedintlen){length=len;//目录长度data=d;//目录内容}Content(Content&other);unsignedchar*data;unsignedintlength;};}#endif5.1.2Umdparser这个文件是整个程序的执行规范,涉及到压缩和解压缩函数的实现,因此需要依赖包zlib,并且需要UMD命名空间的定义,即addition.h。文件来实行响应操作后的动作定义umdparser.h:#ifndefUMDPARSER_H#defineUMDPARSER_H#include<stdlib.h>#include<stdio.h>#include<stdarg.h>#include<memory.h>#include<string.h>#include<vector>#include"../include/Additions.h"namespaceUMD{classUmdParser{public:UmdParser();~UmdParser();public:intParse(char*pFileName); //对路径文件进行解压Head*getHead(); //对头进行取址Cover*getCover(); //取封面std::vector<Chapter*>getChapters(); //取章节std::vector<Content*>getBlocks(); //取块数据private:voidReadSection(shortid,unsignedcharb,unsignedcharlength);voidReadAdditional(shortid,unsignedintcheck,unsignedintlength);intParseHeader();//intParseContent();voidFreeMemory(); //关闭文件后释放空间,除了“最近文档”的数据FILE*m_pUMDFile;unsignedlongm_nUMDFileSize;unsignedchar*m_pUMDBuffer;unsignedchar*m_pCurrent;unsignedshortm_nPkgSeed;unsignedintm_nCid;unsignedintm_nAdditionalCheck;unsignedintm_nContentLength;intm_nChapLen;unsignedint*m_pChapOffset;Head*head;Cover*cover;std::vector<Content*>data_blocks;std::vector<Chapter*>chapters;};}#endif//UMDPARSER_H在上面的代码中我们不难发现,这是对UMD的解压和读取操作,其作用类似于数学里面的公式的作用,即操作规范。这和之前的命名空间不同,命名空间负责定义,这里负责规范操作。5.1.3bookmarkwidget书签插件设计书签插件的定义,包含在bookmarkwidget.h的头文件中,之后再书签功能的实现里面会详细介绍#ifndefBOOKMARKWIDGET_H#defineBOOKMARKWIDGET_H#include<QtGui>classBookMarkWidget:publicQListWidget{Q_OBJECTpublic:explicitBookMarkWidget(constQString&bookName,QWidget*parent=0);//书签插件的定义voidsetTextEdit(QTextEdit*te){textEdit=te;}voidsaveBookMark(constQString&name); //书签的保存voidsaveBookMarks(); voidreadBookMarks(); //书签的读取boolgotoBookMark(constQString&name,intindex); //书签的使用boolremoveBookMark(constQString&name,intindex); //书签的删除private:voidinitList(); //初始化书签列表voidcreateMenu(); //右键弹出书签菜单的定义QTextEdit*textEdit;QStringbookTitle; //书的题目QList<int>bookMarkPosition; //书签的位置QStringListbookMarkTitle; //书签的题目QMenu*bookMarkManagerMenu; //书签管理右击菜单的鼠标指针区域QAction*addBookMarkAction; //添加书签QAction*delBookMarkAction; //删除书签QAction*renameBookMarkAction; //重命名书签protected:voidcontextMenuEvent(QContextMenuEvent*event); //设置右击菜单为友元privateslots:voidonBookMarkSelected(constQModelIndex&index);voidaddBookMark();voiddelBookMark();voidrenameBookMark();};#endif//BOOKMARKWIDGET_H这个插件是用于书签的添加,删除,修改操作的定义。而之后具体的操作编程则再“书签功能的实现”一栏里面会提到,这里不做赘述。5.1.4主界面的设计 之后的主要功能设计里面,全部用到这个头文件,所以这里不作简介。主界面的设计包含在MainWindow.h的文件中。#ifndefMAINWINDOW_H#defineMAINWINDOW_H#include<QtGui>#include"../include/UmdReader.h"#include"../include/bookmarkwidget.h"classMainWindow:publicQMainWindow{Q_OBJECTpublic:MainWindow(QWidget*parent=0); //主界面定义voidloadFile(constQString&); //载入文件private:voidcreatWidget(); //定义控件voidcreatAction(); //定义动作voidcreatMenubar(); //定义菜单栏voidcreatToolbar(); //定义工具栏voidcreatConnection(); //定义响应voidsetCurrentFile(constQString&fileName); //设置当前载入的文件voidupdateRecentFileActions(); //设置最近访问的文件QStringstrippedName(constQString&fullFileName);staticconstintMaxRecentFiles=5; //设置最近访问文件的上限为5QTabBar*tabBar;QStackedWidget*stackedWidget;QGroupBox*box;QMenuBar*menuBar;QToolBar*toolBar;UmdReader*currentUmdReader; //在当前打开的文件下面定义所有界面上的按钮等控件的操作QMenu*fileMenu; //文件菜单QMenu*editMenu; //编辑菜单QMenu*viewMenu; //查看菜单QMenu*helpMenu; //帮助QAction*openAction; //打开QAction*saveAsAction; //另存为QAction*atrAction; //属性设定QAction*printAction; //打印QAction*exitAction; //退出QAction*separatorAct; //分隔符QAction*recentFileActs[MaxRecentFiles]; //最近文档QAction*showOrHideAction; //显示或者隐藏QAction*chapterListShowAction; //章节栏显示QAction*bookMarkListShowAction; //书签栏显示QAction*zoomInAction; //放大QAction*zoomOutAction; //缩小QAction*findAction; //查找QAction*findNextAction; //查找下一个QAction*copyAction; //复制QAction*selectAllAction; //全选QAction*addBookMarkAction; //添加书签QAction*toolBarAction; //工具栏QAction*aboutAction; //关于boolshow; //显示与否boolshowBookMark; //显示书签与否boolshowChapter; //显示章节与否QStringbookName; //书名QStringsearchString; //查找字符QVector<UmdReader*>tabs; //标题栏privateslots: //下面是私有操作定义,对应上面的操作voidopenFile();voidopenRecentFile();voidshowAttribute();voidsaveAs();voidcloseTab(intindex);voidzoomIn();voidzoomOut();voidfindString();voidfindNext();voidshowOrHideList(bool);voidshowChapterList(bool);voidshowBookMarkList(bool);voidprint();voidselectAll();voidonCurrentChanged(int);voidcopy();voidabout();voidaddBookMark();};#endif//MAINWINDOW_H5.2主要功能设计5.2.1UMD文件的打开打开功能的实现主要步骤是读取文件路径信息并转换成信号最后执行打开操作。如图5-1a,5-1b,5-1c所示图5-1a按钮图5-1b实现图5-1c打开最近文档动作部分: openAction=newQAction(QIcon(":/resource/pixmap/document_open.png"),QObject::tr("&OpenFile"),this);openAction->setShortcut(QKeySequence::Open);触发部分:connect(openAction,SIGNAL(triggered()),this,SLOT(openFile()));打开最近文档: for(inti=0;i<MaxRecentFiles;i++){ connect(recentFileActs[i],SIGNAL(triggered()),this,SLOT(openRecentFile()));}操作部分:主要功能打开文档的实现voidMainWindow::openFile(){QStringbook=QFileDialog::getOpenFileName(this,QObject::tr("Openaumdbook"),QDir::homePath(),QObject::tr("Documents(*.umd)"));if(!book.isEmpty())loadFile(book);}附属功能打开最近文档的实现:voidMainWindow::openRecentFile(){QAction*act=qobject_cast<QAction*>(sender());QStringbook=act->data().toString();if(act&&QFile::exists(book))loadFile(book);}附属功能读取文件操作的实现: 这个和打开文件的操作类似,是1对多的关系,读取操作中包含:1,打开文件;2,设置部分灰色选项为黑色可用。(不包括“复制”)voidMainWindow::loadFile(constQString&book){QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));tabs.append(newUmdReader(book,this));UmdReader*reader=tabs.last();currentUmdReader=reader;tabBar->addTab(reader->getTitle());stackedWidget->addWidget(qobject_cast<QWidget*>(reader));intcount=tabBar->count();tabBar->setCurrentIndex(count-1);stackedWidget->setCurrentIndex(count-1);reader->showOrHideList(show);QStringtitle("WYS'sEBook");title.append(reader->getTitle());setWindowTitle(title);setCurrentFile(book);QApplication::restoreOverrideCursor();atrAction->setEnabled(true);saveAsAction->setEnabled(true);printAction->setEnabled(true);zoomInAction->setEnabled(true);zoomOutAction->setEnabled(true);addBookMarkAction->setEnabled(true);findAction->setEnabled(true);selectAllAction->setEnabled(true);showOrHideAction->setEnabled(true);showOrHideAction->setChecked(show);chapterListShowAction->setEnabled(true);chapterListShowAction->setChecked(showChapter);bookMarkListShowAction->setEnabled(true);bookMarkListShowAction->setChecked(showBookMark);connect(reader->getEdit(),SIGNAL(copyAvailable(bool)),copyAction,SLOT(setEnabled(bool)));connect(reader->getEdit(),SIGNAL(copyAvailable(bool)),findNextAction,SLOT(setEnabled(bool)));}5.2.2UMD文件的阅览动作部分文档属性查看功能:(详见图5-2a,图5-2b)图5-2a文件属性查看图5-2b属性显示对应代码如下:atrAction=newQAction(QObject::tr("File&Attribute"),this);“查看”选项显示设定:(详见图5-3a,5-3b)图5-3a显示各项插件图5-3b隐藏各项插件对应代码如下:showOrHideAction=newQAction(QObject::tr("SlideBar"),this);//showORhideshowOrHideAction->setEnabled(false);showOrHideAction->setCheckable(true);showOrHideAction->setChecked(false);章节栏显示功能:(详见图5-4)图5-4章节栏显示对应代码如下: chapterListShowAction=newQAction(QObject::tr("ChapterList"),this);//chaptersettingchapterListShowAction->setEnabled(false);chapterListShowAction->setCheckable(true);chapterListShowAction->setChecked(false);书签栏显示功能:(详见图5-5)图5-5书签栏显示对应代码如下:bookMarkListShowAction=newQAction(QObject::tr("BookMarkList"),this);//markingbookMarkListShowAction->setEnabled(false);bookMarkListShowAction->setCheckable(true);bookMarkListShowAction->setChecked(false);放大以及缩小功能:(详见图5-6a,图5-6b)图5-6a放大功能由图5-5a大家看到,点击放大按钮后,正文被放大了。图5-6b缩小功能由图5-5b大家看到,点击缩小按钮后,正文被缩小了。源代码如下所示:zoomInAction=newQAction(QIcon(":/resource/pixmap/zoom_in.png"),//zoomQObject::tr("ZoomIn"),this);zoomInAction->setEnabled(false);zoomOutAction=newQAction(QIcon(":/resource/pixmap/zoom_out.png"),//zoomQObject::tr("ZoomOut"),this);zoomOutAction->setEnabled(false);查找功能:(详见图5-7,包括寻找下一个字符的功能)图5-7查找的功能实现如图5-6所示,我查找了“珍惜”二字,底下就有珍惜以高亮显示。对应源代码如下:findAction=newQAction(QIcon(":/resource/pixmap/search.png"),//findQObject::tr("&Search"),this);findAction->setShortcut(QKeySequence::Find);findAction->setEnabled(false);findNextAction=newQAction(QObject::tr("SearchNext"),this);//find-nextfindNextAction->setShortcut(QKeySequence::FindNext);findNextAction->setEnabled(false);全选功能:(详见图5-8a,图5-8b)图5-8a全选选项图5-8b右键点击selectall全选 如图5-7a和5-7b所示,正文全被选中了。对应源代码如下:selectAllAction=newQAction(QI
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度煤炭资源整合与优化配置合同4篇
- 2024-2030年中国芳纶纤维防护服装行业市场深度研究及发展趋势预测报告
- 2025年中国压裂车行业发展潜力分析及投资方向研究报告
- 番禺中小企业服务联盟2025版章程服务项目实施协议3篇
- 2025年液压开孔器项目投资可行性研究分析报告
- 秦皇岛2025年河北秦皇岛市人民检察院招聘聘用制书记员16人笔试历年参考题库附带答案详解
- 2024年马鞍山市精神康复医院高层次卫技人才招聘笔试历年参考题库频考点附带答案
- 2023-2029年中国石头造纸行业市场发展现状及投资规划建议报告
- 2025年中国冷冻设备制造行业市场发展监测及投资方向研究报告
- 2025年中国餐饮连锁市场竞争格局分析及投资方向研究报告
- 2025年工程合作协议书
- 2025年山东省东营市东营区融媒体中心招聘全媒体采编播专业技术人员10人历年高频重点提升(共500题)附带答案详解
- 2025年宜宾人才限公司招聘高频重点提升(共500题)附带答案详解
- KAT1-2023井下探放水技术规范
- 垃圾处理厂工程施工组织设计
- 天疱疮患者护理
- 驾驶证学法减分(学法免分)题库及答案200题完整版
- 2024年四川省泸州市中考英语试题含解析
- 2025届河南省九师联盟商开大联考高一数学第一学期期末学业质量监测模拟试题含解析
- 抚养权起诉状(31篇)
- 2024年“一岗双责”制度(五篇)
评论
0/150
提交评论