文件I/O编程
一、基本I/O操作
Linux的输入/输出(I/O)操作,通常分为5个方面:打开、读取、写入、定位和关闭;对应的有5个系统调用: open()、read()、write()、lseek()、和close()这5个函数,也称为不带缓冲区的I/O操作。程序员可以直接操作硬件,这样为开发驱动等底层的系统应用提供了方便。这些函数属于POSIX的一部分。其原型如下:
1 #include <sys/types.h> 2 #include <sys/stats.h> 3 #include <fcntl.h> 4 #include <unistd.h>
1 int open(const char *pathname, int flags, mode_t mode); 2 3 size_t read(int fd, void *buf, size_t nbytes); 4 5 size_t write(int fd, const void *buf, size_t ntytes); 6 7 size_t lseek(int fd, off_t offset, int whence); 8 9 int close(int fd);
1.open()函数
open()函数原型如下:
1 int open(const char* pathname, int flags); 2 3 int open(const char* pathname, int flags, mode_t mode);
函数传入的参数的含义如下:
- pathname: 为字符串,表示被打开的文件名称,可以包含路径。
- flags: 为一个或多个标志,表示文件打开的方式,常用标志如下表1所示,flags 参数可以用|进行组合。
- mode: 被打开文件的存取权限模式。
函数返回值:成功返回文件描述符,失败返回-1.
表1 常用 flag 标志
标识符名 | 含义和作用 |
O_RDONLY | 只读方式打开 |
O_WRONLY | 只写方式打开 |
O_RDWR | 读/写方式打开 |
O_CREAT | 如果文件不存在,就创建新的文件 |
O_EXCL | 如果使用O_CREAT时文件存在,则可返回错误消息 |
O_TRUNC | 如果文件已存在,且以只读或只写方式打开,则先全部删除文件中的原有数据 |
O_APPEND | 以添加方式打开文件,在打开文件的同时,文件指针指向文件的末尾 |
2. read()和write()函数
read()和write()函数原型如下:
1 ssize_t read( int fd, void* buf, size_t count); 2 ssize_t write( int fd, void* buf, size_t count);
函数传入的参数含义如下:
- fd:文件描述符
- buf: 指定存储器读出数据的缓冲区
- count: 指定读出或写入的字节数
函数返回值:
如果发生错误,那么返回值为-1,同时设定errno变量为错误代码。如果操作成功,则返回实际读入或写入的字节数。
3. close()函数
当使用完文件时可以使用close()关闭文件,close()会让缓冲区的数据写回磁盘,并释放文件所占用的资源。其函数原型如下:
int close(fd);
函数返回值:成功返回0,失败返回-1,并置errno。
二、标准I/O操作
前面内容所述的文件及I/O读写都是基于文件描述符的。这些都是基本的I/O控制,是不带缓冲的。在高层应用中,不带缓冲的I/O操作往往效率低下。ANSI制定了一系列基于流缓冲的标准I/O函数,是符合ANSI的标准I/O处理。
这些函数基本都定义在C语言标准库的<stdio.h>头文件中。
1.fopen()函数
函数原型如下:
FILE* fopen( const char* pathname, const char* type);
下表说明了type的各种取值:
type 字符串 |
含义 |
R或rb | 打开只读文件,该文件必须存在 |
R+或r+b | 打开可读/可写文件,该文件必须存在 |
W或wb | 打开只写文件,若文件存在,则文件长度清零;否则建立该文件 |
w+或w+b | 打开可读/可写文件,若文件存在,则文件长度清零;否则建立该文件 |
a或ab | 以追加的方式打开可读/可写文件,若文件存在,则写入的数据将附加到文件的尾部,不会修改文件原有的数据;若文件不存在,则建立该文件 |
a+或a+b | 以追加的方式打开只写文件,若文件存在,则写入的数据将附加到文件的尾部,不会修改文件原有的数据;若文件不存在,则建立该文件 |
2.fclose()函数
函数原型如下:
int fclose(FILE* fp);
这时缓冲区的数据写入文件中,并释放系统所提供的文件资源。如果只是希望将缓冲区的数据写入文件,但因为可能后面还要用到文件指针,不希望在这个时候关闭它,可以使用另外的一个函数fflush(),其函数原型如下:
int fflusn(FILE* fp);
3. fread()和fwrite()函数
fread()和fwrite()函数原型如下:
1 size_t fread(void *ptr, size_t size, size_t nmemb, FILE* stream); 2 3 size_t fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream);
返回值:读或写的记录数,成功时返回的记录数等于nmemb,出错或读到文件结尾时返回的记录数小于nmemb,也可能返回0。
fread()和fwrite 用于读/写记录,这里的记录是指一串固定长度的字节,如一个int、一个结构体或者一个定长数组。参数size指出一条记录的长度,而nmemb指出要读出或写多少条记录,这些记录在ptr所指的内存中连续存放,共占size*nmemb字节。
fread()从文件文件stream中读出size*nmemb字节保存到ptr中,而fwrite()把ptr中的size*nmemb字节写到文件stream中。