Linux-----基础I/O函数以及fd与FILE的对比

open函数

用于打开或者创建一个文件。用man open命令查看

函数原型:

       #include 
       #include 
       #include 

       int open(const char *pathname, int flags);

参数说明:
pathname 打开的文件
flags 是打开方式:

 - O_RDONLY 以只读方式打开
 - O_WRONLY以只读方式打开
 - O_RDWR以读写方式打开

 - O_TRUNC  文件清空
 - O_APPEND 文件追加

返回值:

 - 成功:返回文件描述符
 - 失败:-1

open也可以用来创建文件,函数原型为

 int open(const char *pathname, int flags, mode_t mode);

参数说明:

  • pathname:文件名
  • flags:
    • O_CREAT创建文件(必选)
    • ORDWR读写方式
    • O_EXCL 加上这个标志之后,如果文件存在会报错。
  • mode:创建文件的权限,如0644
int fd=open("abc",O_RDONLY);
printf("fd=%d\n",fd);

输出结果:fd=3
stdin  0 是标准输入
stdout 1 是标准输出
stderr 2 是标准错误

read函数

从fd所指文件中读取数据到buf所指的空间,空间大小为len。用man 2 read命令查看

函数原型:

       #include 
       ssize_t read(int fd, void *buf, size_t len);

参数说明:

 - fd:文件描述符
 - buf:读到哪里去
 - len:空间多大

返回值:实际读取的字节数

write函数

往fd所指文件中写入数据,数据的起始地址为buf,大小为len.
函数原型:

      #include 
      ssize_t write(int fd, const void *buf, size_t len);

lseek函数

用man lseek命令查看

函数原型:

       #include 
       #include 

       off_t lseek(int fd, off_t offset, int whence);

参数说明:whence 从哪个地方开始偏移

 - SEEK_SET   文件开头
 - SEEK_CUR 当前位置
 - SEEK_END 文件末尾

返回值:新的相对于文件开头的偏移量。
例题1:
int lseek(fd,2,SEEK_CUR)
含义是 向后偏移两个字节,返回SEEK_CUR到文件开头的距离。
Linux-----基础I/O函数以及fd与FILE的对比_第1张图片

例题2:如何求文件大小??
lseek(fd,0,SEEK_END)
含义为从文件头到文件尾的字节数,也就是文件大小。

close函数

关闭一个文件。用man close命令查看

函数原型:

       #include 
       int close(int fd);

返回值:成功返回0;失败返回-1。

fd与FILE的对比:

文件描述符 fd:

操作系统用一个整数代表打开的文件。进程能打开的文件描述符个数为[0,ulimit -n],ulimit -n是一条命令,可以查看系统最大打开文件个数。
fd在open时产生的,起到一个索引的作用。进程通过PCB中的文件描述符表找到该fd所指向的文件指针file。因此在Linux系统下面,文件描述符主要是被用来标识一个文件。内核通过文件对象表来管理系统中各种各样的文件,而文件表则是通过指针来指向打开的文件,进而达到管理整个文件系统的目的。
Linux-----基础I/O函数以及fd与FILE的对比_第2张图片

文件指针FILE*


文件指针指向进程的用户空间中的一个FILE结构体,文件指针指向进程用户区中的一个被称为FILE结构的数据结构。FILE结构包括一个缓冲区和一个文件描述符,而文件描述符是文件描述符表的一个索引,因此从某种意义上说文件指针就是句柄的句柄(在Windows系统上,文件描述符被称作文件句柄)。
系统对FILE的结构定义如下:

int fileno(FILE * stream)
FILE * fdopen(int fd, const char * mode)

typedef  struct _iobuf {
    char *_ptr;          //缓冲区当前指针
    int   _cnt;
    char *_base;         //缓冲区基址
    int   _flag;         //文件读写模式
    int   _file;         //文件描述符
    int   _charbuf;      //缓冲区剩余自己个数
    int   _bufsiz;       //缓冲区大小
    char *_tmpfname;
}FILE;

C语言中这样获取文件指针

FILE * fp=fopen("test.txt","r");

获取到指针以后,我们就可以获得指针当中文件描述符的信息。
注意:
文件描述符是唯一的,但是文件指针不是唯一的,文件指针指向的对象是唯一的。

    其实,除此之外,我们也应该清楚文件描述符fd和文件指针FILE在系统中所处的位置:
    文件描述符:OS层
    文件指针:lib层(C库) 

lib库是在操作系统上为用户所做的更高一层封装。
封装主要体现在:

(1)缓冲方式:操作系统一般采用的是无缓冲,而lib一般则采用的是全缓冲的方式。
(2)函数封装:在lib层所对应的标准输入std_in,标准输出std_out,标准错误std_err也正好对应着文件描述符的0,1,2。

你可能感兴趣的:(linux基础)