您的位置: turnitin查重官网> 计算机 >> 处理技术 >谈嵌入式嵌入式设备多存储介质媒体库统一查询策略大专

谈嵌入式嵌入式设备多存储介质媒体库统一查询策略大专

收藏本文 2024-03-31 点赞:8279 浏览:26069 作者:网友投稿原创标记本站原创

摘 要:智能手机、带存储介质的嵌入式设备,一般会存储大量的图片、音乐、视频等多媒体文件。只有少部分媒体带有文件的搜索和管理功能,但是功能有限,操作也不统一。首先对磁盘文件目录作递归扫描,根据文件名后缀作过滤和分类,用嵌入式数据库sqlite3来存储扫描结果;然后介绍了分类查询、文件名汉字拼音首字母查询、即输即查的快速模糊查询技术,还特别对多分区和多介质的情况作了处理,支持多介质的统一查询。此方法可用来轻易构建软件,给智能手机或其它嵌入式设备用户一种全方位的媒体库管理体验。
关键词:嵌入式设备;存储介质;模糊查询;媒体库
16727800(2013)003002704
基金项目:国家自然科学基金资助项目(61173049);湖北省自然科学基金资助项目(2012FFB07401)
作者简介:李艳红(1973-),女,博士,中南民族大学计算机科学学院讲师,研究方向为现代数据库。
0 引言
嵌入式技术的日益成熟,特别是近几年来苹果ios设备的IPA开发平台和谷歌Android设备的APK开发平台的日益普及,使得嵌入式设备和智能手机的功能越来越多,应用越来越广泛,也越来越吸引更多的消费者去购写。这些设备和智能手机一般具有内置的存储器,并支持外接储存卡或盘,例如SD卡、MicroSD卡、U盘等。
人们购写这些价值不菲的消费品,最大目的是追求其娱乐功能,而这些娱乐功能大多数与图片、音乐、视频等多媒体文件相关。到目前为止,这些消费品的媒体库管理功能还很弱,特别是在有海量媒体文件的设备上,用户想要快速找到一个特定的文件是一件头疼的事情。文件管理器是标准应用程序,设备自带的是基于文件夹管理,查找文件的功能不强。虽然有些也有一些搜索媒体文件的功能,但也只是将其简单地显示出来。
本文提出的方法,将磁盘文件信息保存到嵌入式数据库,可按“all”、“picture”、“music”、“video”、“others”等类别显示,汉字名称支持拼音首字母查询。对于多存储器及多分区的情况,支持即插即用。对于MP3文件,可按“歌手”、“专辑”、“风格”等id3tag信息来查找。所有查询都能支持即输即查。
由于嵌入式设备以Linux内核居多,包括Android也是运行在Linux之上的系统。所以本文的实验选择Linux运行环境。

1 磁盘扫描及其文件信息存储算法

本节介绍磁盘扫描及其文件信息的存储算法。首先获取当前所有可用的存储器,对每个存储器的每个分区分别进行递归文件扫描;然后根据文件名的后缀名,将文件归属到不同的媒体类别,每种类别的共同属性是“folder”(文件所在的文件夹)、“date”(文件的创建日期)、“pathfile”(包含路径的完整文件名)、“pinyin_i

源于:论文 格式www.udooo.com

nitial_letter”(文件名汉字拼音首字母)等;再根据这些文件的后缀,将这些属性分别存储到“picture”、“music”、“video”、“other”表。

1.1 磁盘扫描

扫描磁盘前,要获取设备已经挂载的存储设备各个分区。最简单的方法是用Linux的‘df’命令来获取,df的输出是stdout,因此需要popen函数来运行该命令,这样df的输出就会重定向到popen函数返回的文件描述符,然后用getline函数逐行读取就可获取到各分区的信息了。“dff | grep‘/dev/’”的输出如表1所示。

1.2 拼音首字母表示文件名

(1)有两个码表文件,一个是简体一个是繁体,每行是一个拼音,拼音之后接空格或者制表符,然后是UTF8编码的汉字,换行为Unix方式0x0A。如图

1、图2所示为文件的片段。

(2)打开这个繁体的码表文件,可看到文件以0xEF、0xBB、0xBF开头,说明是UTF8的文本文件。0x61是‘a’的ASCII码,0x09是制表符,然后是‘阿’的内码0xE998BF…最后0x0A表示换行。下一个是拼音‘ai’。如图3所示。
(3)程序初始化的时候,要将这两个文件的内容读出来进行转换,得到一个由汉字UTF8内码反查拼音首字母的表。表2所示为该表的片段。其中,0xE4BCB8是‘伸’,0XE4BCBA是‘伺’,0XE4BCBC是‘似’,0XE4BCBD是‘伽’,这是个多音字:ga1/qie2/jia1。所以表中放了3个首字母:‘g’‘q’‘j’。
(4)在Linux系统中,是用UTF8来表示文件名和文件夹名的,所以扫描得到的文件名和文件夹名是UTF8的字符串。媒体数据库的表中,可以设一个字段用来存放文件名对应的“首字母串”,比如“还珠格格2”对应“hzgg2”。

1.3 取出MP3标签

MP3的id3tag同时有id3v1和id3v2两种,其中ID3v1放在文件尾部,ID3v2放在MP3文件头部,ID3v2到现在一共有4个版本,但流行的播放软件一般只支持第3版,即ID3v2.3。由于ID3v1记录在MP3文件的末尾,ID3v2就只能记录在MP3文件的首部。也正是由于这个原因,对ID3v2的操作比ID3v1要慢,而且ID3v2结构比ID3v1的结构要复杂得多,但比前者全面且可以伸缩和扩展。
ID3v1比较简单,它是存放在MP3文件的末尾,用16进制的编辑器打开一个MP3文件,查看其末尾的128个顺序存放字节,数据结构定义如下:

1.4 扫描速度提高方法

扫描磁盘、同时将扫描出来的每一个媒体文件(根据文件名后缀来判断)插入到数据库,这需要在不同的位置频繁进行“读取”和“保存”的磁盘操作来完成,处理器的绝大部分时间消耗在来回定位上。如果每次找到一个媒体文件就立即插入到数据库,将会严重降低速度。以硬盘为例,磁头将频繁在读和写的位置来回跑,U盘和SD卡也类似。因而,媒体库扫描策略是使用内存数据库作为临时数据库,当内存数据库达到一定量的数据时,才一次性移到磁盘数据库。实验表明,将数据写入内存数据库,与写入磁盘数据库对比,效率大约能提高10倍。2 多存储器多分区统一查询算法

2.1 单个磁盘查询情况

(1)sqlite3的db的select语句支持limit(相当于长度)和offset(总体结果集中第几个记录开始,最小值为0),只考虑单个db很简单,对于给定的key,先用\[select count(*)from where like '%%key%%';\]语句得到结果集总行数,这只是用于显示。
(2)然后可以用\[select*from
where like'%%key%%' limit m offset 0\]最先显示前m个(例如一屏10行)。
(3)用户下翻屏,很容易就计算出下一屏的sql语句里limit是10,而offset是10;再下翻,limit是10,offset是20。

2.2 将各分区的数据库存储到各分区的统一查询算法

(1)对于分布N个磁盘的N个table情况如何呢?要逐个求得各自符合key记录的总行数,得到M=m1+m2+…+mn,也是用于显示。
(2)对每个表设置两个计数变量up和dn,表示“结果集中的10个中,被挑选出来记录的头尾”,下一次sql语句的offset值,就是根据up、dn和用户操作来计算的。
(3)指定key后的第一次显示,都

源于:论文格式字体要求www.udooo.com

是从结果集的第0条记录开始。用\[select * from where like '%%key%%' limit 10 offset 0\]取第一个db的结果,用\[select*from where like '%%key%%' limit 10 offset 0\]取第二个db的结果……,如图4所示。
(4)把这些候选的行合并,才能决定最终判定哪10个是显示给用户看的,如图5所示。
(5)下翻时从“合并排序后的列表”的头部选择,上翻则在尾部选择。我们需要记录在各个库的10个候选行中各自有几个被选中?检测设n1、n2、n3,n1+n2+n3=10,这些数字都是确定的。例如n1=3、n2=2、n3=5,表示第一个库有3行被选中,第二个库有2行被选中,第三个库有5行被选中。
(6)同时要更新每个库的计数变量up和dn,下翻(刚开始从头开始视为下翻)的更新方法:upx=offx(select 语句中的offset值),dnx=offx+nx。例如up1=0,dn1=3,up2=0,dn2=3,up3=0,dn3=5。如图6所示。
(7)up和dn的值更新完毕,用户的翻屏操作也准备好。Select语句中的offset的计算方法为:offx =(PgDn)?dnx:min(0,upxlimit)。如果是下翻,那么offset为dnx;如果是上翻,则offset为upx,回退limit行(当然最小是0)。
(8)上翻、selecct、合并、选择完毕后的up、dn的计算:dnx=offx+limit,upx=dnx-nx。
2.3 用分区的UUID来区分各个分区,而将各分区的数据库统一存储在设备自带存储器上 UUID的含义是通用唯一识别码(Universally Unique Identifier),是一个软件建构的标准,也是被开源软件基金会(Open Software Foundation, O)的组织在分布式计算环境(Distributed Computing Environment, DCE)领域的一部分。UUID的目的是让分布式系统中的所有元素,都能有唯一的辨识信息。每个软件或设备都可以建立不与其它元素冲突的UUID。目前最广泛应用的UUID,即是微软的Microsoft's Globally Unique Identifiers(GUIDs),而其它重要的应用则有Linux ext2/ext3/ext4文件系统、LUKS加密分区、GNOME、KDE、Mac OS X等。
本文使用的是正式Linux文件系统的UUID,或者说磁盘分区的UUID。可以用Linux命令‘blkid’来查看分区的UUID,例如‘blkid /dev/sda1’会显示出第一个存储设备的第一个分区的信息:
/dev/sda1: UUID="a5eb50-d363-4bdd-a442-0c10f8452d69" TYPE="ext4"
有了磁盘的UUID,就可以不用将数据库保存到各自的分区,而是保存在设备自带的存储器的某个分区(比如第一个分区)。
将不同分区的文件信息数据库,集中保存到设备自带存储器分区主要有两方面的好处:一是大幅减小热插拔操作对移动存储设备的损伤,因为移动存储设备此时不需要挂载成读写模式,只需挂载为只读模式即可;二是可以将每个UUID对应分区的磁盘空间使用情况记录下来,每次扫描时只扫描磁盘空间有变化的分区,可大幅缩短磁盘扫描的时间。

3 实验及结论

本文所述方法已在ubuntu上用实验证实是完全可行的:用popen使得shell命令的输出可以在程序中读取,用df来取得各分区的信息(见表1),然后依次对各个挂载点按1.1节所述算法DiskScan做磁盘扫描。实验中,对照了使用sqlite3内存数据库和没有使用内存数据库的情况,发现对于一个包含1 306个文件的8G U盘,没有使用内存数据库作中转时,时间开销为6

2.9s,而使用了内存数据库中转时,时间开销缩短为5.7s。

之所以选用sqlite3作为数据库,是因为sqlite3是一种效率高、安全可靠又支持sql操作的嵌入式数据库,是绝大多数嵌入式设备程序的首选。
本文所提出的磁盘扫描和统一查询技术,免去了用户在不同分区之间切换和找文件的麻烦。利用首字母模糊查询技术和即输即查技术,用户能非常方便地找到想要播放的文件。
参考文献:
\[1\] (美)Grant Allen, Mike Owens. SQLite权威指南\[M\].第2版.北京:电子工业出版社,2012.
\[2\] 杨树青,王欢.Linux环境下C编程指南\[M\].北京:清华大学出版社,2007.
\[3\] HASSO PLATTNER, ALEXANDER ZEIER. Inmemory data management: technology and applications\[J\]. Springer,2012(4).
\[4\] CHRISTOPHER HALLINAN. embedded linux primer:a practical realworld approach\[J\]. Second Edition. Pearson Education,2012(5).
\[5\] 何晓龙,李明.完美应用Ubuntu\[M\].第2版.北京:电子工业出版社,2008.
(责任编辑:孙 娟)

copyright 2003-2024 Copyright©2020 Powered by 网络信息技术有限公司 备案号: 粤2017400971号