第十周代码学习总结
系统级I/O
输入/输出(I/O)是在主存和外部设备之间拷贝数据的过程。
输入操作是从I/O设备拷贝数据到主存。
I/O→主存
输出操作是从主存拷贝数据到I/O设备。
主存→I/O
Unix I/O
所有的I/O设备都被模型化为文件。
所有的输入和输出都被当作对相应文件的读和写来执行。
打开文件
应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备。
内核返回一个小的非负整数,称为描述符。
内核记录有关这个打开文件的所有信息。
应用程序只需要记住操作符即可。
创建每个进程开始时三个打开的文件
标准输入(描述符为0)|STDIN_FILENO
标准输出(描述符为1)|STDOUT_FILENO
标准错误(描述符为2)|STDERR_FILENO
改变当前的文件位置
对于打开的文件,内核保存着该文件的位置k,初始值为0
k为从文件开头起始的字节偏移量
应用程序通过执行seek操作,显式地设置文件的当前位置为k
读写文件
读操作:
从文件拷贝n>0个字节到存储器
从当前文件位置k开始
将k增加到k+n
给定一个大小为m字节的文件,当k≥m时(即当前文件位置已到文件尾),此时执行读操作会触发end-of-file(EOF)条件。
在文件的结尾并未明确的EOF符号
写操作:
从存储器拷贝n>0个字节到一个文件
从当前文件位置k开始
更新k
关闭文件
应用完成对文件的访问后,会通知内核关闭该文件。
内核释放文件打开时创建的数据结构,并恢复描述池。
无论一个进程因为何种原因终止,内核都会关闭所有打开的文件并释放它们的存储器资源。
一些头文件的用处:
stdio.h 标准输入输出
stdlib.h C标准函数库
unistd.h Unix类系统定义符号常量
fcntl.h 定义了很多宏和open,fcntl函数原型
sys/types.h 基本系统数据类型
dirent.h unix类目录操作的头文件,包含了许多UNIX系统服务的函数原型,例如opendir函数、readdir函数。
termios.h 在Posix规范中定义的标准接口
、cp的作用就是读取一个文件的内容到存储器,在新的地址创建空白文件,再从存储器将内容写入新文件。(如下图把ls1.c复制,存为lc.c文件)
#include <stdio.h>//标准输入输出
#include <stdlib.h>//C标准函数库
#include <unistd.h>//Unix类系统定义符号常量
#include <fcntl.h>//定义了很多宏和open,fcntl函数原型
#define BUFFERSIZE 4096//定义存储器容量
#define COPYMODE 0644//定义复制的长度
voidoops(char *, char *);intmain(int argc, char *argv[])
{
int in_fd, out_fd, n_chars;//三个描述符值
char buf[BUFFERSIZE];//存储器位置
/*cp的参数有两个,分别是要复制的文件,和目的目录,这样一共应该是有三个操作数
所以要先检查argc的值是否为三,如果不是,返回标准错误*/
if (argc != 3) {
fprintf(stderr, "usage: %s source destination\n", *argv);
exit(1);
}
/*检查cp的第一个参数,要复制的文件,用open打开,in_fd为open返回的描述符
如果返回-1,代表打开失败,提示错误*/
if ((in_fd = open(argv[1], O_RDONLY)) == -1)
oops("Cannot open ", argv[1]);
/*检查cp的第二个参数,复制的目的地址,用create在目的地址创建新文件,out_fd为open返回的描述符
如果返回-1,代表创建失败,提示错误*/
if ((out_fd = creat(argv[2], COPYMODE)) == -1)
oops("Cannot creat", argv[2]);
/*cp指令的动作就是读取一个文件的内容到存储器,在新的地址创建空白文件,再从存储器将内容写入新文件。
这里判断复制是否成功:
如果能读取顺利,而读取的位数和写的位数不同,是写错误;
如果读取失败,是读错误。*/
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]);
/*这里执行的是关闭文件的动作,in_fd和out_fd两个文件描述符
所指向的文件只要有一个关闭错误,就提示关闭错误。*/
if (close(in_fd) == -1 || close(out_fd) == -1)
oops("Error closing files", "");
}/*这个是用来输出错误信息的函数*/
voidoops(char *s1, char *s2)
{
fprintf(stderr, "Error: %s ", s1);
perror(s2);//用来将上一个函数发生错误的原因输出到标准设备(stderr)
exit(1);
}
ls1程序的作用是在当前目录显示文件名(未带参数直接显示,带参数的存入argc)
3
、ls2不仅显示了文件名,还用来显示文件的详细信息
3、spwd代码的功能是列出当前目录。
who1.c
本函数实际是实现who功能的函数,用于显示包含在结构体utmp中的用户的用户名,用户的登录时间等相关信息。具体如下:
参考资料:
http://www.cnblogs.com/20135202yjx/ 闫佳歆同学博客
深入理解计算机系统
百度百科