Linux中,较高级的I/O函数(如printf(),scanf()等)都是通过使用内核提供的系统级Unix I/O函数来实现的。虽然我们用起这些较高级的I/O函数都觉得非常顺手,但是学习系统级I/O函数仍存在许多意义,正如《深入理解计算机系统》一书中写道:
1.了解Unix I/O会帮助我们理解其他的系统概念。系统I/O与其他系统概念经常会形成循环依赖,比如I/O函数在系统进程创建和执行中非常重要,而进程的创建又在不同进程的文件共享中扮演着关键角色;
2.有时除了Unix系统级I/O以外别无选择。在某些重要的情况中,使用高级的I/O函数不太可能,比如:标准I/O库中没有提供读取文件元数据的方式,例如文件大小或文件创建时间。
了解完系统级I/O的重要性,接下来介绍一下本篇博客的主体目录:
下面来进入我们的第一个部分:
“Linux中,一切皆文件”,我的《深入了解计算机系统》的老师如是说道。一个功能完整的机器,所有的设备/文件等等是海量的,那么应当如何单独地描述标记一个文件呢?这时我们就需要引入一个文件描述符(fd,一个非负数)的概念。一个应用程序通过要求内核打开相应的文件时,内核会返回一个非负数,这个非负数就是这个相应的文件的文件标识符fd。
解释完fd是什么,进入正题。Unix I/O中,所有的I/O都由一种“统一而且一致的方式”来执行,各种Unix I/O函数如下:
open()的函数原型如下:
#include
#include
#include
int open(char *filename, int flags, mode_t mode);
/*返回值:若成功则返回文件fd,不成功则为-1。*/
/*函数参数:filename:文件名;flags:进程访问文件的方式对应的参数;mode:访问权限位*/
接下来对flags及mode进行进一步的解析:
了解完各种flags,我们可以知道它与open()的多种联用:
fd=open("foo.txt",O_WRONLY|O_APPEND,0);
/*打开一个文件,并在后面追加一些数据。*/
fd=open("foo.txt",O_CREAT|O_TRUNC|O_WRONLY,DEF_MODE);
/*若文件名对应的文件不存在,则创建;*/
/*若文件名对应的文件存在,则截断(清空)文件内的原内容,并将权限设置为可写。*/
各种访问权限位在头文件sys/stat.h中定义,以掩码的形式表现出来,如下:
代码如下,理解起来简单,故不作赘述:
#include
int close(int fd);
/*成功返回0,不成功返回-1.,,x'x*/
系统级的读写主要是通过调用read()和write()实现的,他们的代码如下:;
include<unistd.h>
ssize_t read(int fd, void *buf, size_t n);
/*若成功则返回读的字节数,若EOF则返回0,若失败则返回-1。*/
ssize_t write(int fd, const void *buf, size_t n);
/*若成功则返回写入的字节数,若出错则为-1。*/
/*变量名解释:fd;文件描述符;buf:read()时读入字节的存储位置,write()时被写入字节的来源;n:读写操作字节数数量。*/
了解了这么多系统级的I/O函数,接下来看看在Linux命令符提示窗口下可能会帮助到我们使用系统级I/O的指令。
ls指令可以查看指定文件的目录结构(包括目录和文件夹),但只限于文件和文件夹的名称。比如接下来我们来用ls指令来查看根目录下的子目录(“/”代表根目录):
cat指令用于显示文件中的内容,语法为cat+(选项)+(文件列表参数/路径);
其选项有以下几种:
各自的运行截图如下:
chmod指令用于改变文件的属性(即改变文件的访问权限位),语法为chmod+mode+file;其中mode代表权限设定字串,格式为:[ugoa][±=][rwxX];其中:
下面使用上述指令给出例子:
chmod ugo+r file.txt
chmod u+x file.txt
cp指令用于复制文件或者文件夹,它有两种用法:
$ cp src-file target-file
$ cp src1 src2 src3 ... target-directory
了解完系统级I/O和相关的Linux指令,我们来看《CSAPP》一书中推荐的I/O函数:
《CSAPP》中有如下几条关于I/O函数使用的原则:
以上便是我个人对于Linux系统级I/O及相关指令操作文档的汇总,其中包含了系统级I/O函数的汇总,一些十分有用且有趣的Linux指令,以及《CSAPP》一书中对于I/O函数使用的建议。希望这能对大家有所帮助。