码迷,mamicode.com
首页 > 其他好文 > 详细

文件操作

时间:2018-08-19 13:05:34      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:不能   read   stat结构体   文件控制   enc   封装   缓冲   描述符   关闭   

1 概念

  对一个文件的操作有两种不同的方式,既可以使用由操作系统直接提供的编程接口,即系统调用,也可以使用由标准C库提供的标准I/O函数。C库里面的很多函数实际上都是对系统调用函数的进一步封装而已。

2 系统I/O

2.1 打开文件

  int open(const char *pathname, int flags)

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

  代码中打开一个文件,是获得这个文件的访问句柄。flags的取值是按位或的方式叠加起来的,mode是八进制权限。其返回值就是一个代表这个文件的描述符,是一个非负整数。这个整数将作为以后任何系统I/O函数对其操作的句柄,或称入口。

2.2 关闭文件

  int close(int fd)

  系统调用close()相对来讲简单的多,只需要提供已打开的文件描述即可。

2.3 读/写接口

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

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

  这两个函数都非常容易理解,需要特别注意的如下几点。

  (1)实际的读/写字节数要通过返回值来判断,参数count只是一个“愿望值”

  (2)读/写操作同时对f_pos起作用。也就是,不管是读还是写,文件的位置偏移量(即内核中的f_pos)都会加上实际读/写的字节数,不断地往后偏移。

2.4 位置偏移量

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

  注意,lseek()只对普通文件有效,特殊文件是无法调整偏移量的。

  我们不仅可以通过lseek()来调整当前文件偏移量,甚至还可以将位置偏移量调整到文件之外,形成一个空洞,它提供了可以在不同地方同时写一个文件的可能。

2.5 赋值文件描述符

  int dup(int oldfd)

  int dup2(int oldfd, int newfd)

2.6 文件控制

  int ioctl(int d, int request, ...)

  int fcntl(int fd, int cmd, .../*arg*/)

  长期以来人们习惯了将除了读和写这样的常规动作之外的其他文件操作放到ioctl()中去实现,所以里面乱七八糟的功能都有,没有借口规范。后来有了规范接口的fcntl()来肃清乱哄哄的场面。

2.7 内存映射

  void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)

  我们极少使用mmap来读写普通文件的数据,更安全可靠且易懂的方式是read()/write(),但有些特殊文件只能用映射内存来读/写,比如LCD液晶屏。

3 标准I/O

  标准I/O接口实际上是系统I/O的封装,它提供了更加丰富的读/写方式。标准I/O是围绕所谓的“文件描述符”进行的,标准I/O都是围绕所谓的“文件指针”进行的。

3.1 打开文件

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

3.2 关闭文件

  int close(FILE *fp)

  该函数用于释放由fopen()申请的系统资源,包括释放标准I/O缓冲区内存,因此fclose()不能对一个文件重复关闭。

3.3 读写接口

  每次读写一个字符的接口

  int fgetc(FILE *stream)

  int getc(FILE *stream)

  int getchar(void)

 

  int fputc(int c, FILE *stream)

  int putc(int c, FILE *stream)

  int putchar(int c)

 

  每次读写一行的接口

  char *fgets(char *s, int size, FILE *stream)

  char *gets(char *s)

 

  int fputs(const char *s, FILE *stream)

  int puts(const char *s)

 

  每次读/写若干数据块的接口

  size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

  size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

  

3.4 文件偏移量

  设置偏移量接口

  int fseek(FILE *stream, long offset, int whence)

  获取当前位置偏移量

  long ftell(FILE *stream)

  将指定文件的当前位置偏移量设置到文件开头处

  void rewind(FILE *stream)

3.5 标准格式化I/O函数

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

  int printf(const char *restrict format, ...)

  int snprintf(char *restrict s, size_t n, const char *restrict format, ...)

  int sprintf(char *restrict s, const char *restrict format, ...)

 

  int fscanf(FILE *restrict stream, const char *restrict format, ...)

  int scanf(const char *restrict format, ...)

  int sscanf(const char *restrict s, const char *restrict format, ...)

 

4 文件属性

4.1 获取文件的元数据

  int stat(const char *path, struct stat *buf)

  int fstat(int fd, struct stat *buf)

  int lstat(const char *path, struct stat *buf)

  这3个函数的功能完全一样,区别是:stat()参数是一个文件的名字,而fstat()的参数是一个已经被打开了的文件的描述符fd,而lstat()则可以获取链接文件本身的属性。

4.2 获取主次设备号函数

  int major(dev_t dev)

  int minor(dev_t dev)

  dev: 文件的设备号属性,来自stat结构体中的st_dev或st_rdev

 

文件操作

标签:不能   read   stat结构体   文件控制   enc   封装   缓冲   描述符   关闭   

原文地址:https://www.cnblogs.com/campus16/p/9500695.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!