设为首页 加入收藏

TOP

Linux 下几个文件操作命令的代码实现(四)
2011-03-18 13:01:29 来源:IBM 作者: 【 】 浏览:2746
Tags:Linux 文件 操作 命令 代码 实现
ntf(stderr,"open error %s \n",strerror(errno)); exit(1); } if(fstat(fd,fp)== -1){ fprintf(stderr,"fstat error %s \n",strerror(errno)); exit(2); } if(fp->st_size > (SIZE-1)){ fprintf(stderr,"buffer size is not big enough \n"); exit(3); } if(read(fd,buf,fp->st_size) == -1){ fprintf(stderr,"read error.\n"); exit(4); } p1=strchr(buf,NLINE); p2=strrchr(buf,NLINE); *p2='\0'; do{ p2=strrchr(buf,NLINE); p4=p2; p3=p2+sizeof(char); printf("%s\n",p3); *p4='\0'; }while(p2 != p1); if(p2 == p1){ *p2 = '\0'; printf("%s\n",buf); } return 0; }

让我们来运行一下该程序:

程序的运行情况如下,假设编译后的可执行文件名为 emulatetac,有一个文本文件 test.txt。

# gcc emulatetac.c -o emulatetac # cat test.txt 1 2 3 a b # ./emulatetac test.txt b a 3 2 1

可以看出文件内容以倒序方式显示输出了。

tac 命令实现的说明

下面逐行讲解:

  • #include 的头文件,都应该通过 man 2 系统调用命令来查找,这里就不多说了。
  • 下面定义了一个宏常量 SIZE,该常量主要用来表示能够读入最大多少个字节的文件,当文件过大的时候程序就不执行,直接退出。然后定义了宏常量 NLINE 表示换行符'\n'。
  • 接下来主程序体开始了:首先定义一个字符数组 buf,用来把读入文件的每个字节都存在该数组里面。
  • 然后定义了 4 个字符串指针,一个指向结构体 struct stat 的指针 fp,一个文件描述符。
  • 然后为指向结构体的指针 fp 分配存储空间。
  • 接下来判断输入参数是否为 2 个,也就是命令本身和文件名。不是 2 个就直接退出。
  • 然后以只读方式打开输入文件名的文件,也就是 test.txt。打开成功的话,把打开的文件赋值到文件描述符 fd 中,错误的话退出。
  • 然后用 fstat 系统调用把文件描述符 fd 中对应文件的元信息,存放到结构体指针 fp 指向的结构中。
  • 下面判断当文件的大小超过缓冲区数组 buf 的大小 SIZE-1 时,就退出。
  • 下面将把文件 test.txt 中的每个字符存放到数组 buf 中。
  • 下面是程序的核心部分:首先我们找到字符串 buf 中的第一个换行字符存放到 p1 指针里面,然后把最后一个换行字符置为字符串结束符。
  • 接下来我们从后往前查找字符串 buf 中的换行符,直到遇到第一个换行符 p1。同时打印每个找到的换行符'\n'中的下一个字符开始的字符串,也就刚好是一行文本。
  • 最后当从后向前找到第一个换行字符时,打印第一行,程序结束。
 


df 命令的实现

df 命令的模拟实现

通过 strace 命令查看 df 主要使用了如下的系统调用:open、fstat、read、statfs

我这里实际上是模拟实现的 df --block-size=4096 这个命令,也就是说以 4096 字节为块大小来显示磁盘使用情况。

这里最为关键的是 statfs 这个结构体,该结构体的某些字段被用作 df 命令的输出字段:

struct statfs { long f_type; /* type of filesystem (see below) */ long f_bsize; /* optimal transfer block size */ long f_blocks; /* total data blocks in file system */ long f_bfree; /* free blocks in fs */ long f_bavail; /* free blocks avail to non-superuser */ long f_files; /* total file nodes in file system */ long f_ffree; /* free file nodes in fs */ fsid_t f_fsid; /* file system id */ long f_namelen; /* maximum length of filenames */ };

比如:df --block-size=4096 的输出如下(纵向列出):

Filesystem /dev/sda1 4K-blocks 5077005    f_blocks 字段 Used 145105    f_blocks 字段 -f_bfree 字段 Available 4669841    f_bavail 字段 Use% 4%   (f_blocks-f_bfree)/ f_blocks*100% 来计算磁盘使用率。 Mounted on /

模拟实现的代码如下:


清单 5. 模拟实现代码
#include <stdio.h> #include <errno.h> #include <stdlib.h> #include <string.h> #include <sys/vfs.h> #include <math.h> #define SIZE1 100 #define FN "/etc/mtab" #define SPACE ' ' int displayapartition(char * pt,char * pt1); int main(void){ char tmpline[SIZE1]; FILE * fp; char * pt1; char * pt2; char * pt3; if( (fp = fopen(FN,"r")) == NULL ){ fprintf(stderr,"%s \n",strerror(errno)); exit(5); } while( fgets(tmpline, SIZE1, fp) != NULL ){ pt1=strchr(tmpline, SPACE); pt2=pt1+sizeof(char); *pt1='\0'; pt3=strchr(pt2,SPACE); *pt3='\0'; if(strstr(tmpline,"/dev") != NULL ){ displayapartition(tmpline,pt2); } } return 0; } int displayapartition(char * pt,char * pt1){ struct statfs buf; statfs(pt1,&buf); int usage; usage=ceil((buf.f_blocks-buf.f_bfree)*100/buf.f_blocks); printf("%s ",pt); printf
首页 上一页 1 2 3 4 下一页 尾页 4/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇C 编程最佳实践 下一篇Linux 中的零拷贝技术,第 2 部分

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: