> 文章列表 > 【Linux】系统文件接口

【Linux】系统文件接口

【Linux】系统文件接口

目录

一、C文件接口

1、fopen

2、fprintf

3、snprintf

二、系统文件IO

1、open

2、write

3、read

4、C文件接口与系统文件IO的关系


一、C文件接口

1、fopen

FILE *fopen(const char *path, const char *mode);

  fopen 函数返回值类型为 FILE 。参数列表中, path 为文件路径, mode 为打开方式。

 打开文件的方式有如下几种:

r 打开文本文件进行阅读。
流位于文件的开头。
r+ 开放读和写。
流位于文件的开头。
w 打开文件进行写入。如果文件不存在,则创建该文件,否则文件被清空。
流位于文件的开头。
w+ 开放读和写。如果文件不存在,则创建该文件,否则文件被清空。
流位于文件的开头。
a 打开以追加(在文件末尾写入)。
如果文件不存在,则创建该文件。
流位于文件的末尾。
a+ 打开以进行读取和追加(在文件末尾写入)。
如果文件不存在,则创建该文件。用于读取的初始文件位置位于文件的开头,
但输出始终附加到文件末尾。

2、fprintf

int fprintf(FILE *stream, const char *format, ...);

printf 不同, printf 默认向显示器打印消息,而 fprintf 则可以指定文件流,向指定文件打印。

编写如下代码:

  1 #include <stdio.h>2 3 #define LOG "log.txt"4 5 int main()6 {7   FILE* fp = fopen(LOG, "w");8   if(fp == NULL)9   {10     perror("fopen");11     return 1;12   }13 14   const char* msg = "hello world";                                                                                                      15   int cnt = 5;16   while(cnt)17   {18     fprintf(fp, "%s: %d: ljb\\n", msg, cnt);19     //fputs(msg, fp);20     cnt--;21   }22 23   fclose(fp);24   return 0;25 }

运行观察结果:

 也可以使用 fprintf 函数向显示器文件里打印,以实现和 printf 函数相同的效果:

3、snprintf

int snprintf(char *str, size_t size, const char *format, ...);

 snprintf 函数可以把内容打印到缓冲区里,并且通过设置参数 size 控制打印的长度。

编写如下代码:

  1 #include <stdio.h>  2   3 #define LOG "log.txt"  4   5 int main()  6 {  7   FILE* fp = fopen(LOG, "w");  8   if(fp == NULL)  9   {  10     perror("fopen");11     return 1;12   }13   14   const char* msg = "hello world";15   int cnt = 5;16   while(cnt)17   {18     char buffer[256];19     snprintf(buffer, sizeof(buffer), "%s: %d:ljb\\n", msg, cnt);20     printf("%s", buffer);21   }                                                                                                                                     22                                                                                                                               23   fclose(fp);                                                                                                                 24   return 0;                                                                                                                   25 } 

 运行观察结果:

二、系统文件IO

1、open

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

 open 函数参数列表中, pathname 为文件路径与文件名, flags 为要打开文件的选项(以位图形式传递), mode 为打开文件的权限。返回值为文件描述符

flags参数:

  • O_RDONLY:只读打开
  • O_WRONLY:只写打开
  • O_RDWR:读,写打开
  • O_CREAT:若文件不存在,则创建它。需要使用mode选项,来指明新文件的访问权限
  • O_APPEND:追加写(需要配合O_WRONLY使用)
  • O_TRUNC:将文件清空

返回值:

  • 成功:新打开的文件描述符
  • 失败:-1
     

 编写如下代码:

  1 #include <stdio.h>2 #include <sys/types.h>3 #include <sys/stat.h>4 #include <fcntl.h>5 #include <unistd.h>6 #include <errno.h>7 #include <string.h>8 9 #define LOG "log.txt"10 11 int main()12 {13   umask(0);                                                                                                                             14   int fd = open(LOG, O_CREAT | O_WRONLY, 0666);                                                                 15   if(fd == -1)                                                                                                  16   {                                                                                                             17     printf("fd: %d, error: %d, errstring: %s\\n", fd, errno, strerror(errno));                                   18   }                                                                                                             19                                                                                                                 20   else                                                                                                          21     printf("fd: %d, error: %d, errstring: %s\\n", fd, errno, strerror(errno));                                   22                                                                                                                 23   close(fd);                                                                                                    24                                                                                                                 25   return 0;                                                                                                     26 }   

 其中 O_CREAT O_WRONLY 为宏定义,传递参数 flags  O_CREAT 为如果文件不存在,则自动创建该文件。 O_WRONLY 为以只读模式打开文件。需要注意的是,他们不会对原始文件内容做清空,下一次写入时,虽然还是从开头开始写,但是原本的内容没被覆盖的部分仍然会残留

运行观察结果:

 如图所示,打开文件所返回的文件描述符 3

 刚刚被创建的 log.txt 文件的权限为 666 

2、write

ssize_t write(int fd, const void *buf, size_t count);

 write 函数的参数列表中, buf 为缓冲区首地址, count 为本次读取,期望写入多少个字节的数
据。 返回值:实际写了多少字节数据。

编写如下代码:

  1 #include <stdio.h>2 #include <sys/types.h>3 #include <sys/stat.h>4 #include <fcntl.h>5 #include <unistd.h>6 #include <errno.h>7 #include <string.h>8 9 #define LOG "log.txt"10 11 int main()12 {                                                                                                                                       13   umask(0);14   int fd = open(LOG, O_CREAT | O_WRONLY, 0666);15   if(fd == -1)16   {17     printf("fd: %d, error: %d, errstring: %s\\n", fd, errno, strerror(errno));18   }19   else20     printf("fd: %d, error: %d, errstring: %s\\n", fd, errno, strerror(errno));21 22   const char* msg = "hello world";23   int cnt = 5;24   while(cnt)25   {26     char line[128];27     snprintf(line, sizeof(line), "%s, %d\\n", msg, cnt);28 29     write(fd, line, strlen(line));30     cnt--;31   }32 33   close(fd);34 35   return 0;36 }

 需要注意的是,这里的数据字节数使用的是 strlen(line) ,而不是 strlen(line) + 1 。这是因为字符串最后一定要加 '\\0' 是C语言的规定,而不是文件的规定。

3、read

ssize_t read(int fd, void *buf, size_t count);

 read 函数的参数列表中, buf 为缓冲区首地址, count 为本次读取,期望读取多少个字节的数
据。 返回值:实际读取了多少字节数据。 

 编写如下代码:

  1 #include <stdio.h>2 #include <sys/types.h>3 #include <sys/stat.h>4 #include <fcntl.h>5 #include <unistd.h>6 #include <errno.h>7 #include <string.h>8 9 #define LOG "log.txt"10 11 int main()12 {                                                                                                                                    13   umask(0);                                                                                                                          14   int fd = open(LOG, O_RDONLY);                                                                                                      15   if(fd == -1)                                                                                                                       16   {17     printf("fd: %d, error: %d, errstring: %s\\n", fd, errno, strerror(errno));18   }19   else20     printf("fd: %d, error: %d, errstring: %s\\n", fd, errno, strerror(errno));21 22   char buffer[1024];23 24   ssize_t n = read(fd, buffer, sizeof(buffer) - 1);25   if(n > 0)26   {27     buffer[n] = '\\0';                                                                                                                   28     printf("%s\\n", buffer);29   }30 31   close(fd);32 33   return 0;34 }

 使用系统接口来进行IO的时候,一定要注意 '\\0' 的问题。

运行观察结果:

4、C文件接口与系统文件IO的关系

 fopen、fclose、fwrite、fputs、fread、fgets 都是C标准库当中的函数,我们称之为库函数(libc)。
 open、close、write、read都属于系统提供的接口,称之为系统调用接口。

 可以认为,f#系列的函数,都是对系统调用的封装,方便二次开发。


关于系统文件接口的内容就讲到这里,希望同学们多多支持,如果有不对的地方欢迎大佬指正,谢谢!