文件IO实际是API,Linux对文件操作主要流程为:打开(open),操作(write、read、lseek),关闭(close).
1.打开文件函数open():
涉及的头文件:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
函数原型:
int open(const char *pathname, int flags); //pathname是要打开的文件名,可以包括路径。flags有:O_RDWR/O_RDONLY/O_WRONLY,分别表示以可读写/只读/只写模式打开,可与O_APPEND(追加)、O_TRUNC(把文件长度设为0,丢弃已有内容)、O_CREAT(当文件不存在时创建,一般要与O_EXCL合用,否则打开的文件存在时,会把原文件覆盖,加上O_EXCL后,原文件存在时,会打开报错 file exists),当O_APPEND与O_TRUNC 一起使用时,O_TRUNC会屏蔽O_APPEND的作用。
一般在open时,都要判定是否打开成功,当返回值为-1时,打开失败,成功时,返回文件描述符(fd),该描述符就与该文件绑定,之后再操作文件,都是针对文件描述符的,fd是一个正整数,出错时可用perror("提示符");打印出错信息。
int open(const char *pathname, int flags, mode_t mode); //一般用到O_CREAT时才用到,mode参数用于指定创建的文件的权限,如0666
2.操作
write函数涉及的头文件:
#include <unistd.h>
函数原型:
ssize_t write(int fd, const void *buf, size_t count); //fd:文件描述符,buf:需要写入的内容指针,count:需要写入的byte数,ssize_t:实际写入字节个数,有时候count会小于ssize_t,因为可能文件中没有count个字节。
----------------------------------------------------------
read函数涉及的头文件:
#include <unistd.h>
函数原型:
ssize_t read(int fd, void *buf, size_t count); ///fd:文件描述符,buf:需要读入的内容指针,count:需要读入的byte数,ssize_t:实际读入字节个数,有时候count会小于ssize_t,因为可能文件中没有count个字节。
----------------------------------------------------------
文件指针操作lseek()涉及的头文件:
#include <sys/types.h>
#include <unistd.h>
函数原型:
off_t lseek(int fd, off_t offset, int whence); //fd:文件描述符,offset:偏移量,whence:定义该偏移值的用法,取值:SEEK_SET/SEEK_CUR/SEEK_END,分别表示:文件指针指向文件起始,文件指针指向当前位置,文件指针指向文件末尾。返回值为文件指针移动到指定位置的偏移量,这里的单位是byte
3.关闭
close()涉及的头文件:
#include <unistd.h>
函数原型:
int close(int fd); //关闭文件,成功返回0,失败返回 -1
补充:linux实现文件共享的方式,即创建不同的fd指向同一个文件。可能出现以下几种情况:
a. 同一进程中多次open(),获取不同fd;未使用O_APPEND,分别写,使用后,接续写。O_APPEND会在一个fd中的文件指针移动后,通知另一个fd的文件指针,让其移动,实现接续写
b.多个进程open(),获取fd指向同一文件;分别写
c.使用dup(与close配合可重定位标准输出,返回的fd由系统分配),dup2复制文件指针(返回的fd可自定)。接续写,得到的fd都指向原来的文件,close只需关闭被复制的文件描述符即可。
标准IO,实际是C库函数,由库函数把系统API封装而来。库函数比API好一点的地方是API不可以通用,不可移植,而C库函数在不同操作系统中几乎是一样的。 可移植性好。
常用的有fopen()、fread()、fwrite()、fclose()、fflush()(标准io有带缓冲区,等缓冲区满时才会写,当需要立即写时,调用此函数便不会等待io缓冲区满,而是直接写),flseek(). 具体用法 man 3 库函数名