计算机系统基础——IO
Input是指从设备拷贝数据到内存,而Output是从内存拷贝数据到外部设备的过程,我们平时使用的都是语言提供的标准IO库,如printf和scanf,这些是通过内核提供的系统级IO函数来实现的。
1.打开和关闭文件
打开文件:进程通过open函数来打开一个已存在的文件或者创建一个新文件。
filename:是文件名
flags:O_RDONLY|O_WRONLY|O_RDWR;(O_CREAT\O_TRUNC\O_APPEND);
mode:访问权限
int open(char *filename,int flags,mode_t mode);
返回:若成功则为新文件描述符;出错则为-1
进程通过调用close函数关闭一个打开的文件。
int close(int fd);
返回:若成功则为0,否则为-1
2.读写文件

fd:描述符fd的当前位置;buf:存储器位置;n:拷贝大小
(注:当读取时遇到EOF、从终端读取文本行或者读写网络套接字的时候返回不足值)
3.读取文件元
文件元数据是指文件本身的一些信息,包含:访问模式、大小和创建时间。
应用程序可以通过调用stat和fstat函数,检索到关于文件的元信息。

4.共享文件

内核通过三个数据结构表示打开的文件:
描述符表:每个独立的进程1张,指向一打开的文件表;
文件表:包括打开文件位置,引用数量,以及一个指向元数据的v-node指针;
v-node表:包含stat结构的大部分信息;

同一个进程的不同表项,通过文件表指向了同一个位置

带缓存的io和非缓存的io
不带缓存的io操作:
在linux操作系统中,read(),write()等系统调用是不带缓存的io操作,其将应用进程中的字节写入内核缓冲区,然后调用fsync()函数同步到磁盘。
带缓存的io操作:
在应用进程中,也有一个文件缓冲区,直到此缓冲区填满之后,再调用read(),write()等系统调用,将数据放入内核缓冲区。
代码运行:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define BUFFERSIZE 4096
#define COPYMODE 0644 //文件权限位
void oops(char *, char *);
int main(int argc, char *argv[])
{
int in_fd, out_fd, n_chars;
char buf[BUFFERSIZE];
//操作错误,描述符不为3,输出提示后退出。
if (argc != 3) {
fprintf(stderr, "usage: %s source destination\n", *argv);
exit(1);
}
//读取文件出错,提示错误后退出。
if ((in_fd = open(argv[1], O_RDONLY)) == -1)
oops("Cannot open ", argv[1]);
//创建文件出错,提示错误后退出
if ((out_fd = creat(argv[2], COPYMODE)) == -1)
oops("Cannot creat", argv[2]);
while ((n_chars = read(in_fd, buf, BUFFERSIZE)) > 0)
if (write(out_fd, buf, n_chars) != n_chars)
oops("Write error to ", argv[2]);//写入文件出错,提示错误后退出
if (n_chars == -1)
oops("Read error from ", argv[1]);//读取文件出错提示错误后退出
//关闭文件流失败,提示错误后退出
if (close(in_fd) == -1 || close(out_fd) == -1)
oops("Error closing files", "");
}
//输出错误消息函数
void oops(char *s1, char *s2)
{
fprintf(stderr, "Error: %s ", s1);
perror(s2);
exit(1);
}
输出结果:
运行成功:

运行失败:

1250

被折叠的 条评论
为什么被折叠?



