1.在Linux中,一切(或几乎一切)都是文件。
2.删除一个文件时,实质上是删除了该文件对应的目录项,同时指向该文件的链接数减1。该文件中的数据可能仍然能够通过其他指向同一文件的链接访问到。
3.三个重要的设备文件:/dev/console(系统控制台)/dev/tty(控制终端)和/dev/null(空设备)。所有写向这个设备的输出都将被丢弃,而读这个设备会立刻返回一个文件尾标志,所以在cp命令里可以把它用做复制空文件的源文件。
4.用于访问设备驱动程序的底层函数(系统调用):open close read write ioctl(把控制信息传递给设备驱动程序)
5.使用库函数,相对于系统调用,极大的降低了系统调用的开销。
6.可以通过文件描述符访问打开的文件或设备。
7.write的作用是把缓冲区buf的前nbytes个字节写入与文件描述符fildes关联的文件中。它返回实际写入的字节数 size_t write(int fildes,const void *buf,size_t nbytes);
8.从与文件描述符fildes相关联的文件里读入nbytes个字节的数据,并把它们放到数据区buf中。它返回实际读入的字节数,这可能会小于请求的字节数。
size_t read(int fildes, void *buf,size_t nbytes);
9.open建立了一条到文件或设备的访问路径。如果调用成功,它将返回一个可以被read、write和其他系统调用使用的文件描述符(唯一)。
int open(const char *path,int oflags);
int open(const char *path,int oflags, mode_t mode);
oflags:打开模式
三选一,必选项:
O_RDONLY只读打开,O_WRONLY只写打开,O_RDWR 读写打开。
可选项:
O_APPEND 将写入追加到文件的尾端
O_CREAT 若文件不存在,则创建它。使用该选项时,需要第三个参数mode,用来指定新文件的访问权限位
O_EXCL 如果同时指定了O_CREAT,而文件已经存在,则会出错
O_TRUNC 如果此文件存在,而且为只写或读写模式成功打开,则将其长度截短为0
O_NOCTTY 如果pathname指的是终端设备,则不将该设备分配作为此进程的控制终端
O_NONBLOCK 如果pathname指的是一个FIFO文件、块设备文件或字符设备文件,则此选项将文件的本次打开操作和后续的I/O操作设置为非阻塞模式
10.使用close调用终止文件描述符fildes与其对应文件之间的关联
int close(int fildes);
11.提供了一个用于控制设备及其描述符行为和配置底层服务的接口
int ioctl(int fildes, int cmd, ...)
12.lseek系统调用对文件描述符fildes的读写指针进行设置
off_t lseek(int fildes, off_t offset, int whence);
offset参数用来指定位置,whence定义offset的用法,如:SEEK_SET:offset为绝对地址,SEEK_CUR:相对于当前位置的偏移,SEEK_END:相对于文件尾的偏移
lseek返回从文件头到文件指针被设置处的字节偏移值
13.fstat系统调用返回与打开的文件描述符相关的文件的状态信息,该信息将会写到一个buf结构中,buf的地址以参数形式传递给fstat,同类型还有stat lstat
14.dup系统调用提供了一种复制文件描述符的方法,使我们能够通过两个或者更多个不同的描述符来访问同一个文件
int dup(int fildes);返回新的描述符
int dup2(int fildes, int fildes2);指定新的描述符fildes2
15. FILE *fopen(const char *filename,const char *mode),mode选项如下
是否可读 | 写入模式 | 文件状态要求 | |
r | 是 | 否 | 必须存在 |
r+ | 是 | 覆盖写 | 必须存在 |
w | 否 | 清空再写 | 不存在则创建 |
w+ | 是 | 清空再写 | 不存在则创建 |
a | 否 | 追加 | 不存在则创建 |
a+ | 是 | 追加 | 不存在则创建 |
16.测试r+写入模式
待写入文件word1.txt
读取文件word2.txt
int case49()
{
printf("\n\ncase49:\n");
char buff[64] = {'\0'};
size_t ret = 0;
FILE *fp1 = fopen("word2.txt","r");
FILE *fp2 = fopen("word1.txt","r+");
if (NULL == fp1 || NULL == fp2)
{
printf("open error...\n");
return -1;
}
do
{
ret = fread(buff,64,1,fp1);
fwrite(buff,64,1,fp2);
memset(buff,'\0',64);
}while(ret == 1);
fclose(fp1);
fclose(fp2);
return 0;
}
运行结果:word1.txt变成如下,原来的内容还有部分未被覆盖
17.文件流错误
int ferror(FILE *stream);检查文件流中是否有错误标识,没有返回0
int feof(FILE *stream);检查文件流是否到文件尾,没有返回0
18.标准库和系统调用为文件和目录的创建与维护提供了全面的支持。例如chmod chown unlink link mkdir等等等等等
19.先用open创建一个文件,然后对其调用unlink是某些程序员用来创建临时文件的技巧。这些文件只有在被打开的时候才能被程序使用,当程序退出并且文件关闭的时候它们就会被自动删除掉。
20.与目录操作有关的函数在dirent.h头文件中声明。其使用方法与用来操作普通文件的文件流(FILE *)非常相似。相关函数:opendir,closedir,readdir,telldir,seekdir,closeddir
21.错误处理
许多系统调用和函数会在失败时设置外部变量errno的值来指明失败的原因,错误代码的含义和取值在errno.h中定义
char *strerror(int errnum);把错误代码映射为一个字符串,该字符串对发生的错误类型进行说明
void perror(const *s);perror函数也把errno变量中报告的当前错误映射到一个字符串,并把它输出到标准错误输出流。该字符串的前面先加上字符串s(如果不为空)中给出的信息,再加上一个冒号和一个空格。
22.Linux提供了一个特殊的文件系统procfs,它通常以/proc目录的形式呈现。该目录中包含了许多特殊文件用来对驱动程序和内核信息进行更高层的访问。
例如: