文件操作二之BMP在系统调用层中的实现

        之前用标准输入输出流写了读取文件的程序,现在用系统调用来实现。在实现之前,还是应该先说明一下,库函数与系统调用的关系,既然说到这儿了,顺便把系统调用与设备驱动的关系也摆一摆i。

    先从设备驱动说起,设备驱动提供了操作设备的方法,方式。对于程序猿来说,就是提供了一组API,我们可以使用这些函数来操作硬件,而不用管硬件里面如何实现(比如硬件的时序和硬件寄存器如何使用等),我们只需要明白函数实现什么功能,需要什么参数,然后就提供相应的参数供函数使用就OK了。

    但是你看,我说的是使用,而不是调用,这意味着有些时候(在linux里面是大多时候)我们并不直接调用这些函数,为什么呢,那些函数干嘛去了呢,这些问题由os来回答,这也是os的作用,os提供了核心,而核心有时候会对这些函数做包装,使他们具有统一的形式(说白了就是提供一种统一的访问方式,比如都用open来打开啊之类的,是为了方便程序猿调用的,以及增加代码可读性。可惜的是,本来是为了方便我们使用的东西,在我们理解系统时,确成了拦路虎)。OK,系统中有些函数是不需要操作硬件的,比如printf等,这些就直接由内核提供原函数,加上我们刚刚说的包装出来的函数,以及一些不用包装的驱动函数,这些加一起,共同构成了一个函数库,而这个函数库,暂且称为系统层函数库(准确的说是提供系统调用)。

    在往应用层走的时候,在映射一次,就映射成为了我们通常指的库函数。而我们使用库函数执行程序的时候,库函数就往下去寻找映射到它的系统层函数库,然后交给系统层函数库执行系统层函数库对应的代码,或者操作硬件或者操作cpu。而寻找系统层库函数的继而由系统层库函数来执行的过程,就被称作是系统调用。很多的函数都有着对应的系统调用。

   

           上次我们写的stdio对应的标准输入输出流就是对应的应用层。比如:fread,这个函数对应的系统调用就是 open。 虽然他们的参数不同,但是在调用的过程中系统会完成参数的转换。

 

#include <fcntl.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <string.h>

 

//开始先定义关于BMP特征的头文件以及特征文件

typedef struct BITFILEHEADER

{

    u_int16_t  bfType;

    u_int16_t bfSize;

    u_int16_t bfReserved1;

    u_int16_t bfReserved2;

    u_int32_t biOffBits;

}  BITFILEHEADER;

typedef struct BITFILEINFOHEADER

{

    u_int32_t biSize;

    u_int32_t biWidth;

    u_int32_t biHeight;

    u_int16_t biPlanes;

    u_int16_t biBitCount;

    u_int32_t biCompression;

    u_int32_t biSizeImage;

    u_int32_t biXPelsPerMeter;

    u_int32_t biYPelsPerMeter;

    u_int32_t biClrUsed;

    u_int32_t biClrImportant;

}     BITFILEINFOHEADER;

 

int main ()

{

    int file_desc = open ("/home/Upan/4.4.bmp" , O_RDWR);

    BITFILEHEADER myhead;

    BITFILEINFOHEADER myinfo;

 

    read ( file_desc , &myhead , sizeof (BITFILEHEADER) );

    read ( file_desc , &myinfo , sizeof (BITFILEINFOHEADER));

   

    printf ( "The size of BITFILEHEADER is %d \n" , sizeof (BITFILEHEADER));

    printf ( "The type number of the file is %d \n" , head.bfType);

 

    close (file_desc);

    return 0;

}

 

从这个程序可以看出来各个函数对应的系统调用各是什么,同时要注意的是,为什么第二个read读取出来的就是info的信息而没有head的信息呢,这个是因为对文件的读写在系统内部也是有一个指针的,上一次的read读完之后,指针已经指向了info的数据块,而不是read之前的文件的起始处了。所以再次直接读取文件的时候内容就不同了。对于文件的读写指针的操作通过系统调用 lseek 来实现。可以用来设置文件的下一个读写位置。且可以根据需要设置绝对位置或者相对当前位置,或者文件尾的相对位置。so wise ,isn't it?

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值