一些文件相关的系统调用 例如open/read/write/close
open
int open(const char* filename, int flags, mode_t mode);
- filename:文件名
- flags:打开文件的方法
- mode:若文件不存在,设置新文件的权限
- 返回值:成功则返回文件描述符,否则返回-1
flags 用于指定文件的打开/创建模式,这个参数可由以下常量(定义于fcntl.h)通过逻辑位或逻辑构成。
O_RDONLY 只读模式
O_WRONLY 只写模式
O_RDWR 读写模式
打开/创建文件时,至少得使用上述三个常量中的一个。
以下常量是选用的:
O_APPEND 每次写操作都写入文件的末尾
O_CREAT 如果指定文件不存在,则创建这个文件
O_EXCL 如果要创建的文件已存在,则返回-1,并且修改errno的值
O_TRUNC 如果文件存在,并且以只写/读写方式打开,则清空文件全部内容(即将其长度截短为0)
O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
O_NONBLOCK 如果路径名指向FIFO/块文件/字符文件,则把文件的打开和后继I/O
例如:
int fd = open("myfile", O_RDWR | O_CREAT, 0664);
if(fd < 0)
{
perror("open");
return -1;
}
创建文件”myfile”, 赋予权限664, 通过读写方式打开
read
size_t read(int fd, void* buf, size_t count);
- 作用: 从fd里读取count大小的数据到buf中
- 返回值: 如果顺利read()会返回实际读到的字节数,最好能将返回值与参数count 作比较,若返回的字节数比要求读取的字节数少,则有可能读到了文件尾、从管道(pipe)或终端机读取,或者是read()被信号中断了读取动作。当有错误发生时则返回-1,错误代码存入errno中,而文件读写位置则无法预期。
示例:
char *file = "hello,wrold\n";
char *buf[1024];
while(1)
{
ssize_t s = read(fd, buf, strlen(file));
printf("s = %d\n", s);
if(s > 0)
{
printf("%s\n", buf);
}
else
return -1;
}
write
ssize_t write(int fd, const void* buf, size_t nbyte);
- 作用: 把buf中的nbyte大小的数据写入fd
- 返回值: 写入文档的字节数(成功);-1(出错)
write函数把buf中nbyte写入文件描述符handle所指的文档,成功时返回写的字节数,错误时返回-1.
示例:
const char* file = "hello,world\n";
char *msg = "world,hello\n";
ssize_t sw = write(fd, msg, strlen(file));
if(sw < 0)
{
perror("write");
return -1;
}
close
int close(int fd);
- 返回值:成功返回0,出错返回-1 并设置errno
参数fd是要关闭的文件描述符。需要说明的是,当一个进程终止时,内核对该进程所有尚未关闭的文件描述符调用close关闭,所以即使用户程序不调用close,在终止时内核也会自动关闭它打开的所有文件。但是对于一个长年累月运行的程序(比如网络服务器),打开的文件描述符一定要记得关闭,否则随着打开的文件越来越多,会占用大量文件描述符和系统资源。
文件描述符
文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。
习惯上,
标准输入(standard input)的文件描述符是 0
标准输出(standard output)是 1
标准错误(standard error)是 2
POSIX 定义了
STDIN_FILENO、
STDOUT_FILENO
STDERR_FILENO
来代替 0、1、2。
这三个符号常量的定义位于头文件 unistd.h。
文件描述符的有效范围是 0 到 OPEN_MAX。一般来说,每个进程最多可以打开 64 个文件(0 — 63)。对于 FreeBSD 5.2.1、Mac OS X 10.3 和 Solaris 9 来说,每个进程最多可以打开文件的多少取决于系统内存的大小,int 的大小,以及系统管理员设定的限制。Linux 2.4.22 强制规定最多不能超过 1,048,576 。
文件描述符是由无符号整数表示的句柄,进程使用它来标识打开的文件。文件描述符与包括相关信息(如文件的打开模式、文件的位置类型、文件的初始类型等)的文件对象相关联,这些信息被称作文件的上下文。
FILE结构体
#ifndef _FILE_DEFINED
struct _iobuf
{
char *_ptr; //文件输入的下一个位置
int _cnt; //当前缓冲区的相对位置
char *_base; //指基础位置(即是文件的其始位置)
int _flag; //文件标志
int _file; //文件的有效性验证
int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取
int _bufsiz; //缓冲区大小
char *_tmpfname; //临时文件名
};
typedef struct _iobuf FILE;
上面结构体中的 _file 实际上是一个描述符,作为进入打开文件表索引的整数。
就是我们说的文件描述符