IO及文件系统

文章详细介绍了Linux系统中的标准C库IO、缓存类型(全缓存、行缓存、无缓存)、文件描述符的使用,以及文件IO的系统调用如open、read、write等。同时,讨论了不同类型的IO模型,包括阻塞、非阻塞、IO多路转换等,并提到了文件属性和权限管理。
摘要由CSDN通过智能技术生成

B站链接视频学习:Linux系统程序设计--线程_哔哩哔哩_bilibili

1.标准C的IO  

c库标准头文件位置 `/usr/include`

typedef struct iobuf{
	int cnt;  /** 剩余的字节数 */
	char *ptr;  /** 下一个字符的位置 */
	char *base; /** 缓冲区的位置 */
	int flag; /** 文件访问模式 */
	int fd; /** 文件描述符,内核提供 */
	//......
}FILE;

2.缓存类型

 **全缓存**

   要求填满整个缓冲区后才进行IO系统调用。对于磁盘文件通常使用全缓存访问;  

- **行缓存**

   涉及一个终端时(标准输入输出)使用行缓存  

   行缓存满或碰到换行符自动输出;

- **无缓存**

   标准错误流stderr通常是不带缓存的,这样可以使错误消息尽快地显示出来;

3.文件描述符

对于内核而言,所有打开文件都由文件描述符引用,文件描述符是一个非负的整数。  

   当打开一个现存文件或创建一个新文件时,内核向进程返回一个文件描述符。  

   在POSIX应用程序中,整数0,1,2被替换成符号常数STDIN_FILENO,STDOUT_FILENO和STDERR_FILENO;它们在头文件 `#include <unistd.h>` 中定义;

   文件描述符的范围是0-OPEN_MAX;linux为024;

文件描述符与FILE的互转:

   FILE *fdopen(int fd,const char *mode); //将文件描述符转FILE指针;  

   int fileno(FILE *stream); // 将文件指针转成文件描述符;  

4.文件IO的系统调用  

1. [open](#open)  

  2. [read](#read)  

  3. [write](#write)  

  4. [lseek](#lseek)

  5. close

5.IO处理

 1)**阻塞的IO模型**

   若所调用的IO函数没有完成相关的功能就会使进程挂起,直到相关数据到达才会返回;常见终端、网络设备访问;

2) **非阻塞的IO模型**

   当请求的IO操作不能完成时,则不让进程休眠,而且返回一个错误;

 3)**IO多路转换模型**

   如果请求的IO操作阻塞,且他不是真正阻塞IO,而且让其中一个函数等待,在这期间,IO可以进行其它操作;  

4) **信号驱动的IO模型**

   在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来,从而启动IO;  

5) **异步的IO模型**

   在这种模型下,当一个描述已经准备好,可以启动IO时,进程会通知内核。由内核进行后续处理;  

6.文件属性

struct stat {
    dev_t     st_dev;         /* 包含文件的设备的ID */
    ino_t     st_ino;         /* i节点数 */
    mode_t    st_mode;        /* 文件类型及权限 */
    nlink_t   st_nlink;       /* 硬链接数 */
    uid_t     st_uid;         /* 所有者的用户ID */
    gid_t     st_gid;         /* 所有者的组ID */
    dev_t     st_rdev;        /* 设备ID(如果是特殊文件) */
    off_t     st_size;        /* 总大小(bytes) */
    blksize_t st_blksize;     /* 文件系统I/O的块大小 */
    blkcnt_t  st_blocks;      /* 分配的512B块数 */
    struct timespec st_atim;  /* 上次访问时间 */
    struct timespec st_mtim;  /* 上次修改时间 */
    struct timespec st_ctim;  /* 上次状态更改时间 */
};

7.文件属性与操作函数 

   [lstat](#lstat) 函数类似于stat,但是当命名的文件是一个符号链接时,lstat返回该符号链接的相关信息而不是该符号引用的文件信息;

   文件操作相关的最基本元素有:目录结构(目录项)、索引节点(i node)、文件数据本身

8.文件类型

在linux中有七种文件类型对应七种宏:    

   | 序号 | 文件类型  | 宏 | 

   | 1 | 普通文件(regular file) | S_ISREG() |  

   | 2 | 目录文件(directory file) | S_ISDIR() |

   | 3 | 块特殊文件(block special file) | S_ISBLK() |

   | 4 | 字符特殊文件(chatacter special file) | S_ISCHR() |

   | 5 | FIFO(named pipe) | S_ISFIFO() |

   | 6 | 套接字(socket) | S_ISSOCK() |

   | 7 | 符号链接(symbolic link) | S_ISLNK() |

9.文件权限

- **九种文件访问权限位**

   

   1. 用户(拥有者)权限  

   S_IRUSR、S_IWUSR、S_IXUSR  

   2. 组权限  

   S_IRGRP、S_IWGRP、S_IXGRP  

   3. 其它权限  

   S_IROTH、S_IWOTH、S_IXOTH  

10.fputs  fprintf

int fputs( const char *s, FILE *fp ); // 把字符串 s 写入到 fp 所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF;  

把字符串 s 写入到 fp 所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF

int main()
{
   FILE *fp = NULL;
   fp = fopen("test.txt", "w+");
   fprintf(fp, "hello world...\n");
   fputs("hello world2...\n",fp);
   fclose(fp);
}

11.fgets  fscanf

`char *fgets( char *buf, int n, FILE *fp )` 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。  

   如果这个函数在读取最后一个字符之前就遇到一个换行符 '\n' 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符。  

   `int fscanf(FILE *fp, const char *format, ...)` 函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取;  

#include <stdio.h>
 
int main()
{
   FILE *fp = NULL;
   char buff[255];
 
   fp = fopen("/tmp/test.txt", "r");
   fscanf(fp, "%s", buff);
   printf("1: %s\n", buff );
   fgets(buff, 255, (FILE*)fp);
   printf("2: %s\n", buff );
   fgets(buff, 255, (FILE*)fp);
   printf("3: %s\n", buff );
   fclose(fp);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值