lseek,fseek,fcntl,ioctl

lseek函数 

文件偏移

Linux中可使用系统函数lseek来修改文件偏移量(读写位置)

每个打开的文件都记录着当前读写位置,打开文件时读写位置是0,表示文件开头,通常读写多少个字节就会将读写位置往后移多少个字节。但是有一个例外,如果以O_APPEND方式打开,每次写操作都会在文件末尾追加数据,然后将读写位置移到新的文件末尾。lseek和标准I/O库的fseek函数类似,可以移动当前读写位置(或者叫偏移量)。

    回忆fseek的作用及常用参数。 SEEK_SET、SEEK_CUR、SEEK_END

    int fseek(FILE *stream, long offset, int whence);  成功返回0;失败返回-1

 特别的:超出文件末尾位置返回0;往回超出文件头位置,返回-1

    off_t lseek(int fd, off_t offset, int whence); 失败返回-1;成功:返回的值是较文件起始位置向后的偏移量。

特别的:lseek允许超过文件结尾设置偏移量,文件会因此被拓展。

    注意文件“读”和“写”使用同一偏移位置。                                               【lseek.c】

lseek常用应用:                     

    1. 使用lseek拓展文件:write操作才能实质性的拓展文件。单lseek是不能进行拓展的。  

                  一般:write(fd, "a", 1);                                                                   

             od -tcx filename  查看文件的16进制表示形式

             od -tcd filename  查看文件的10进制表示形式      

                  

2. 通过lseek获取文件的大小:lseek(fd, 0, SEEK_END);             【lseek_test.c】

    【最后注意】:lseek函数返回的偏移量总是相对于文件头而言。                

fcntl函数

改变一个【已经打开】的文件的 访问控制属性。

     重点掌握两个参数的使用,F_GETFL 和 F_SETFL。                                                                                               【fcntl.c】

ioctl函数

对设备的I/O通道进行管理,控制设备特性。(主要应用于设备驱动程序中)。

     通常用来获取文件的【物理特性】(该特性,不同文件类型所含有的值各不相同)                            【ioctl.c】

传入传出参数

传入参数: 

const 关键字修饰的 指针变量  在函数内部读操作。  char *strcpy(cnost char *src, char *dst);

传出参数:   

1. 指针做为函数参数

2. 函数调用前,指针指向的空间可以无意义,调用后指针指向的空间有意义,且作为函数的返回值传出 

3. 在函数内部写操作。

传入传出参数:

1. 调用前指向的空间有实际意义 2. 调用期间在函数内读、写(改变原值)操作 3.作为函数返回值传出。

扩展阅读:

关于虚拟4G内存的描述和解析:

一个进程用到的虚拟地址是由内存区域表来管理的,实际用不了4G。而用到的内存区域,会通过页表映射到物理内存。

所以每个进程都可以使用同样的虚拟内存地址而不冲突,因为它们的物理地址实际上是不同的。内核用的是3G以上的1G虚拟内存地址,

其中896M是直接映射到物理地址的,128M按需映射896M以上的所谓高位内存。各进程使用的是同一个内核。

首先要分清“可以寻址”和“实际使用”的区别。

其实我们讲的每个进程都有4G虚拟地址空间,讲的都是“可以寻址”4G,意思是虚拟地址的0-3G对于一个进程的用户态和内核态来说是可以访问的,而3-4G是只有进程的内核态可以访问的。并不是说这个进程会用满这些空间。

其次,所谓“独立拥有的虚拟地址”是指对于每一个进程,都可以访问自己的0-4G的虚拟地址。虚拟地址是“虚拟”的,需要转化为“真实”的物理地址。

好比你有你的地址簿,我有我的地址簿。你和我的地址簿都有1、2、3、4页,但是每页里面的实际内容是不一样的,我的地址簿第1页写着3你的地址簿第1页写着4,对于你、我自己来说都是用第1页(虚拟),实际上用的分别是第3、4页(物理),不冲突。

内核用的896M虚拟地址是直接映射的,意思是只要把虚拟地址减去一个偏移量(3G)就等于物理地址。同样,这里指的还是寻址,实际使用前还是要分配内存。而且896M只是个最大值。如果物理内存小,内核能使用(分配)的可用内存也小。

猜你喜欢

转载自www.cnblogs.com/xiangtingshen/p/10428374.html