每个 Linux 文件都有一个类型(type)来表明它在系统中的角色
-
普通文件(regular file)包含任意数据。应用程序常常要区分文本文件(texs file)和二 进制文件(binary file),文本文件是只含有 ASCII 或 Unicode 字符的普通文件;二
进制文件是所有其他的文件。对内核而言,文本文件和二进制文件没有区别。 -
目录(directory)是包含一组链接(link)的文件,其中每个链接都将一个文件名
(filename)映射到一个文件,这个文件可能是另一个目录。每个目录至少含有两个
条目:“.”是到该目录自身的链接,以及“…”是到目录层次结构(见下文)中父目 录(parent
directory)的链接。你可以用mkdir命令创建一个目录,用1s查看其内 容,用rmdir删除该目录。 -
套接字(socket)是用来与另一个进程进行跨网络通信的文件。
打开和关闭文件 -
进程是通过调用 open函数来打开一个已存在的文件或者创建一个新文件的
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
int open(char *filename,int flags,mode_t mode);
open函数将filename转换为一个文件描述符,并且返回描述符数字。
- O_RDONLY: 只读
- O_WRONLY: 只写
- O_CREAT : 如果文件不存在,就创建一个截断的(truncated)(空)文件。
- O_TRUNC : 如果文件已存在,就截断它(长度被截为0,属性不变)
- O_APPEND: 在每次写操作前,设置文件位置到文件的结尾
读和写文件
#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
-
read函数从描述符fd的当前文件位置拷贝最多n个字节到存储器buf
-
write函数从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置
用RIO包健壮地读 -
无缓冲的输入输出函数。这些函数直接在内存和文件之间传送数据,没有应用级缓冲。它们对将二进制数据读写到网络和从网络读写二进制数据尤其有用。
带缓冲的输入函数。这些函数允许你高效地从文件中读取文本行和二进制数据,这 -
些文件的内容缓存在应用级缓冲区内,类似于为printf这样的标准I/O函数提供
的缓冲区。与[110]中讲述的带缓冲的I/O例程不同,带缓冲的RIO输入函数是线
程安全的(12.7.1节),它在同一个描述符上可以被交错地调用。例如,你可以从一个描述符中读一些文本行,然后读取一些二进制数据,接着再多读取一些文本行。
RIO的无缓冲的输入输出函数
与普通read,write区别
在读写网络套接字的时候不会产生不足值
即rio_writen不可能返回不足值
线程安全的。
当wirte,read被应用信号处理程序的返回中断时,允许手动重启。
RIO的带缓冲的输入函数
一个文本行就是由一个换行符结尾的ASCII码字符序列。
在Unix系统里,换行符(\n)与ASCII码换行符LF相等,数字值为0x0a
读取文件元数据
应用程序能够通过调用stat和fstate函数,检索到关于文件的信息(有时也称为文件的元数据(metadata))
#include<unistd.h>
#include<sys/stat.h>
int stat(const char *filename,struct stat *buf);
int fstat(int fd,struct stat *buf);
//填写stat数据结构中的各个成员
返回 : 成功0 ,出错-1
共享文件
- 描述符表(descriptor table)。每个进程都有它独立的描述符表,它的表项是由进程
打开的文件描述符来索引的。每个打开的描述符表项指向文件表中的一个表项。 - 文件表(file table)。打开文件的集合是由一张文件表来表示的,所有的进程共享这
张表。每个文件表的表项组成(针对我们的目的)包括当前的文件位置、引用计数 (reference
count)(即当前指向该表项的描述符表项数),以及一个指向 v-node表中
对应表项的指针。关闭一个描述符会减少相应的文件表表项中的引用计数。内核不 会删除这个文件表表项,直到它的引用计数为零。 - v-node表(v-node table)。同文件表一样,所有的进程共享这张 v-node 表。每个表项包含stat结构中的大多数信息,包括stmode和st_size成员。
I/O 重定向
I/O重定向如何工作?
使用dup2函数
#include<unistd.h>
int dup2(int oldfd,int newfd);返回:若成功则为非负的描述符,若出错则为-1
C语言定义了一组高级输人输出函数,称为标准1/0库,住贝焚供JUnix1/0
的较高级别的替代。这个库(1ibc)提供了打开和关闭文件的函数(fopen和 fclose)、读
和写字节的函数(fread和 fwrite)、读和写字符串的函数(fgets和 fputs),以及复杂
的格式化的I/O函数(scanf和printf)。
标准I/O库将一个打开的文件模型化为一个流。对于程序员而言,一个流就是一个指
向FILE类型的结构的指针。每个 ANSI C程序开始时都有三个打开的流 stdin、stdout
和 stderr,分别对应于标准输入、标准输出和标准错误.