一、Linux文件结构
文件,除了本身包含的内容以外,还有一个管理信息,包括文件的创建/修改日期和它的访问权限,这些属性被保存在文件的inode(节点)中。
目录是用于保存其他文件的节点号和名字的文件。文件节点号可以通过ln -i 命令查看。
UNIX 与 LINUX 中比较重要的设备文件有3个: /dev/console, /dev/tty 和 /dev/null
/dev/console 代表系统控制台。
/dev/tty 如果一个进程有控制端的话,那么特殊文件/dev/tty就是这个控制终端的别名。
/dev/null 文件是空设备, 所有写向这个设备的输出都将被丢弃。
二、系统调用和设备驱动程序
访问设备驱动程序的底层函数
open: 打开文件或设备
read:从打开的文件或设备里读数据
write:向文件或设备写数据
colse:关闭文件或设备
ioctl: 把控制信息传递给设备驱动程序
三:库函数
为了给设备和磁盘文件提供更高层的接口,Linux和UNIX提供了一系列的标准函数库。
四、底层文件访问
当一个程序开始运行时,它一般人有3个已经打开的文件描述符:
0:标准输入
1:标准输出
2:标准错误
write系统调用原型
#include <stdio.h> size_t write(int fildes, const void *buf, size_t nbytes);
write的作用是把缓冲区buf的前nbytes个字节写入与文件描述符fields关联的文件中。
返回实际写入的字节数。如果返回值为0,则没有写入任何数据。
如果返回是-1,表示出现错误
#include <unistd.h> #include <stdlib.h> int main() { if ((write(1, "Here is some data\n", 18)) != 18) write(2, "A write error has occurred on file descriptor 1\n",46); exit(0); }
read系统调用
#include <unistd.h> size_t read(int fildes, void *buf, size_t nbytes);
从文件描述符fields相关联的文件里读入nbytes个字节的数据,并把它们放到数据区buf中。返回实际读入的字节数。
如果返回0,表示未读入任何数据,已到达文件尾。
如果是-1,表示read出现错误。
#include <unistd.h> #include <stdlib.h> int main() { char buffer[128]; int nread; nread = read(0, buffer, 128); if (nread == -1) write(2, "A read error has occurred\n", 26); if ((write(1,buffer,nread)) != nread) write(2, "A write error has occurred\n",27); exit(0); }
open系统调用
#include <fcntl.h> #include <sys/types.h> #include <sys/stat.h> int open(const char *path, int oflags); int open(const char *path, int oflags, mode_t mode)
open建立了一条到文件或设备的访问路径。如果成功,它将返回一个可以被read,write和其他系统调用使用的文件描述符(唯一的),不会与任何其他运行中的进程共享。
path是准备打开的文件或设备的名字, oflags参数用于指定打开文件所采取的动作。
oflags必选模式:
O_RDONLY 以只读方式打开
O_WRONLY 以只写方式打开
O_RDWR 以读写方式打
oflags可选模式
O_APPEND 把写入数据追加在文件末尾
O_TRUNC 把文件长度设置为零,丢弃已有内容
O_CREAT 如果需要,就按参数MODE中给出的访问模式创建文件
开O_EXCL 与O_CREAT一起使用
open在调用成功时,返回一个新的文件描述符(非负整数)。