我的C语言学习历程:进阶篇




从“压缩管理器”向“文件管理器”进化

到了0.87版,我已经将程序的名字改成“文件管理器”,因为那时我觉得,PC版的7-zip都有文件管理器的功能,同是压缩软件的“压缩管理”也应该具备文件管理器的功能,就这样,我又开始写代码,为了实现文件管理器。

先看看一些截图:

我的C语言学习历程:进阶篇_第1张图片我的C语言学习历程:进阶篇_第2张图片

我的C语言学习历程:进阶篇_第3张图片

文件管理器0.87版的主界面直接显示空间信息,源代码修改自之前的“压缩管理”中的路径选择菜单,第一张图中显示的空间信息有误,在后来的更新中才解决掉这个问题,“本地磁盘”的背景为红色,表示当前选中的是“本地磁盘”,按下↓键可以选中“存储卡”,存储卡的检测,我是直接读取根目录下的proc文件夹中的某个文件实现的,存储卡处于移除状态,该文件内容为REMOVE,存储卡为插入状态,内容就会是INSIDE。

让getch函数支持方向键,我采用的方法是:接受第一个按键键值后,创建一个线程,用于再次接受按键键值,等1000毫秒后,终止这个线程,之后,将子线程获取的键值与刚刚得到的键值相加,就得到了一个新的键值,改进版的getch函数的源代码在这里:http://blog.csdn.net/liuchao35758600/article/details/6419499


第二张图是更新后的效果。上面一排的文字是功能选项,最初只有三个,日后的更新中新增至5个;

按F键即可显示字符下拉菜单,具体看第三张图,下拉菜单中的选项也有对应的快捷键,但在后来的更新中已经去掉快捷键了。

实现这些字符界面,使用了转义序列,具体可见此贴:http://club.noahedu.com/viewthread.php?tid=118019&highlight=%D7%AA%D2%E5

使用printf函数打印\e[y;xH,就可以将终端的光标定位到y行x列,例如:printf("\e[1;1H");将光标定位到第1行第1列,这时,后面打印的内容就会从这个位置开始显示。


要实现文件管理器的文件浏览功能,首先要能读取文件目录信息,以“linux 遍历文件目录 C”为关键词在网上搜索,找到个合适的代码就复制过来了。

windows 7系统中的资源管理器,可以显示当前文件夹下有多少文件夹和文件,我也模仿实现了这个功能,修改遍历文件目录的源代码,加入文件夹和文件计数功能。

文件列表中应该要显示文件大小,于是就用stat函数在获取文件列表后获取每个文件的大小。

文件列表中应该要按顺序显示,文件夹排前面,文件排后面,我在网上搜索了一下,发现scandir函数生成的文件列表是自动经过排序的,而这个文件列表是用malloc分配的内存存储的,需要free掉;生成的文件列表是文件和文件夹混合的,需要将文件夹和文件分离出来,用for循环判断文件列表中的文件的属性,这个时候我用的是二维数组存储的,静态内存,编译出来的文件也很大。


考虑到浏览的文件目录内的文件和文件夹会很多,用静态内存存储文件列表,存储的数量是有限的,听说有动态内存,网上搜索了一下,用malloc函数分配内存,free函数释放内存,就这样,我把存储文件列表及各个文件的大小的二维数组改成了二维指针,已知文件总数、文件夹数、文件数、每个文件的文件名、每个文件的大小,分配内存也就很好分配,用完后,用free函数释放掉,free函数要和malloc函数成对使用,用了多少次malloc函数就需要用多少次free函数。


至于文件操作,前期版本只支持单文件操作,后来的更新中,实现了多文件操作,具体如下图所示:

我的C语言学习历程:进阶篇_第4张图片

可以标记多个文件,标记的文件存储在二维数组中,同时用一个变量保存已标记的文件的总数。

文件管理器的界面中的左下角显示的内容是变化的,标记文件时显示“已标记N个文件”,移动/复制文件时显示"将XXX文件(或者N个项目)移动/复制至...",没有任何操作时,显示“N个文件夹,M个文件”,实现这个字符界面,主要用的是字符串处理函数,用sprintf函数生成界面每一行的内容,之后再用printf函数显示,没有用system函数调用clear命令清屏,因为这会有闪烁,影响效果,用了转义序列的光标定位功能,将要显示的内容覆盖当前显示的内容。


有的人可能会想,内容有长有短,为什么这个字符UI没有变形?

如果看过之前描述“压缩管理”的功能的那部分,应该可以知道,只是进行了字符串处理,字符串长度少于指定长度则用N个空格填补,多余则截取字符串。

有的时候截取的字符串的末尾会乱码,那是因为把汉字截成两半了,半个汉字无法显示,只能显示成框框,为了解决这个问题,我是用了一种方法:

由于GB2312编码的汉字在char型字符串是占两个字节,每个字节的值都是负数,并且,这个负数都是成对存在,这样,就能很好的处理汉字问题了。


文件的复制/移动/粘贴功能,我参考了windows 7系统中的资源管理器,毕竟它是我模仿的对象,见下图:

我的C语言学习历程:进阶篇_第5张图片

win7的资源管理器在复制/移动文件时会显示进度条以及相关信息,这个功能,经过思考,可以用C语言实现,用到的就是基本数学中的加减乘除。

初始形态:

我的C语言学习历程:进阶篇_第6张图片

经过完善后:

我的C语言学习历程:进阶篇_第7张图片

在复制/移动过程中,会碰到同名文件,win7的资源管理器会显示这样的界面:

我的C语言学习历程:进阶篇_第8张图片

要模仿实现,也很简单,用stat函数获取文件大小和修改日期,之后对比,体积大的就显示“(较大)”,最近修改的就显示“(较新)”,效果如下图所示:

我的C语言学习历程:进阶篇_第9张图片

文件信息查看功能,也模仿了win7的资源管理器:

我的C语言学习历程:进阶篇_第10张图片

我的C语言学习历程:进阶篇_第11张图片

使用这些功能有时会遇到段错误(Segmentation Fault),解决这些问题也用了大量时间。


在文件管理器的N次更新中,添加了文件关联功能,这样就可以调用其它程序打开文件。

我的C语言学习历程:进阶篇_第12张图片

我的C语言学习历程:进阶篇_第13张图片

这个关联信息的显示列表,我用了排序函数,把二维数组重新排序,之后再显示,排序的函数,网上搜索的,具体在哪里也不清楚了。



文件管理器包含了“压缩管理”的功能,并且,能更好的发挥7-zip的强大功能,具体见下图及其说明:

使用文件管理器,可以将多个文件压缩成压缩文件,解压文件时,可以选择任意位置作为解压目录。

我的C语言学习历程:进阶篇_第14张图片我的C语言学习历程:进阶篇_第15张图片

我的C语言学习历程:进阶篇_第16张图片

第一张图是将文件压缩成压缩文件时显示的界面,可以命名压缩文件的名称以及使用的压缩格式。

第二张图是打开压缩文件时显示的界面,只有4个选项:打开、解压、更新、测试,打开就是调用7zip显示文件列表;选择解压,文件管理器会进入当前目录,可以正常浏览文件目录,按V键确定当前位置为解压位置。(看第三张图)


“压缩管理”中的压缩格式的配置功能得到完善,通过按↑键和↓键使光标">>"移动来实现选项的选择,按确定键可选中这个选项。

我的C语言学习历程:进阶篇_第17张图片我的C语言学习历程:进阶篇_第18张图片

“压缩管理”中的IPK安装功能也进行了完善,新增了IPK安装记录,实现这个功能,我还特意研究了学习机,学习机的IPK包安装程序是ipkg-cl,通过调用它来实现IPK包的安装,安装后,会将IPK包信息记录在status文件内,我的“文件管理器”读取这个文件的内容并处理一下就可以了,具体处理方法就不说了。

我的C语言学习历程:进阶篇_第19张图片我的C语言学习历程:进阶篇_第20张图片我的C语言学习历程:进阶篇_第21张图片我的C语言学习历程:进阶篇_第22张图片

在文件管理器中打开ipk安装包时,会先读取ipk包的信息,之后提示是否安装该安装包。(参考第二张图)

如果已经安装过,会提示是替换还是先卸载再安装。(参考第三张图)

可以查看这个安装包的信息,信息保存在control文件内,调用7z命令从安装包中解压指定文件,然后读取,如果没有这个文件,就不会显示安装包的信息。(参考第四张图)

安装后的IPK包,查看信息时,会显示该安装包安装后占用的空间,ipk包安装后,会自动生成ipk包内的文件列表,只需要读取这个文件列表,并累计大小即可得出占用空间大小。



小结

初步了解了如何遍历文件目录,如何获取文件名,如何获取文件的绝对路径,但还是需要借助网络。

了解了7z命令的更多参数的功能及用法。

接触了指针,因为考虑到文件目录内的文件时多时少,为了减少不必要的内存开销,就使用了指针,用malloc函数实现动态内存分配,用free函数释放内存,但有时还是出现段错误(Segmentation Fault)。

进一步掌握了转义字符的用法。

修改了网友分享的getch函数,这个getch函数是模拟实现的,为的是实现无回显接受按键输入。

发现线程间的全局变量不同步,子线程频繁修改全局变量,而主线程获取的全局变量的值不与子线程修改的值同步。


还没接触结构体,结构体是在高三暑期的时候学到的。

你可能感兴趣的:(c,windows,存储,语言,文件管理器,7zip)