文件操作的基本概念参见博客: 小何讲Linux: 底层文件I/O操作
1. 函数说明
2. open()函数语法要点
所需头文件
#include
#include
#include
函数原型
int open(const char *pathname, int flags, int perms)
在操作文件之前,首先必须打开文件。open函数的打开原理就是将进程files_struct结构体和文件对象file相关联。
函数原型
int open(const char *pathname, int flags, int perms)
pathname :被打开的文件名(可包括路径名)。
flags :文件打开的方式(用下列一个或多个常数进行或运算构成定义,这些常数在fcntl.h 中定义)
O_RDONLY :以只读方式打开文件
O_WRONLY:以只写方式打开文件
O_RDWR: 以读写方式打开文件
O_CREAT:如果该文件不存在,就创建一个新的文件,并用第三个参数为其设置权限
O_EXCL:如果使用O_CREAT时文件已存在,则返回错误消息。这一参数可测试文件是否存在。此时open是原子操作,防止多个进程同时创建同一个文件
O_NOCTTY:使用本参数时,若文件为终端,则不将此设备分配作为此进程的控制终端
O_TRUNC:若文件已经存在,那么会删除文件中的全部原有数据,并且设置文件大小为0。
O_APPEND:以添加方式打开文件,在打开文件的同时,文件指针指向文件末尾,即将写入的数据添加到文件的末尾。
O_NONBLOCK 如果pathname指的是一个FIFO、一个块特殊文件或一个字符特殊文件,则该选项将此文件的本次打开操作和后续的I/O操作设置非阻塞方式。
O_SYNC 使每次write都等到物理I/O操作完成
flag参数可通过“| ”组合构成,但前3个标志常量(O_RDONLY、O_WRONLY 以及O_RDWR)不能相互组合。
perms被创建文件的存取权限(仅当创建新文件时才使用)
可以用一组宏定义:S_I(R/W/X)(USR/GRP/OTH)
其中R/W/X分别表示读/写/执行权限
USR/GRP/OTH分别表示文件所有者/文件所属组/其他用户
perms 是文件的存取权限,既可以用宏定义表示法,也可以用八进制表示法。
例如,S_IRUSR | S_IWUSR表示设置文件所有者的可读可写属性。八进制表示法中600也表示同样的权限
S_IRWXU-设置文件所有者具有全部权限。
函数返回值
成功:返回文件描述符(返回的文件描述符一定是最小的未用描述符数字)
失败:-1
3. close()函数语法要点
所需头文件
#include
函数原型
int close(int fd)
函数输入值
fd:文件描述符
函数返回值
0: 成功
-1:出错
4. read()函数语法要点
所需头文件:#include
函数原型:ssize_t read(int fd, void *buf, size_t count)
参数:
fd:文件描述符
buf:指向存放读出数据的缓冲区的指针
count:指定读出的字节数
函数返回值
成功:读到的字节数
0:已到达文件尾
-1:出错(如以非阻塞方式打开的文件上无数据可读时)
注意:
5. write()函数语法要点
所需头文件:#include
函数原型:ssize_t write(int fd, void *buf, size_t count)
参数:
fd:文件描述符
buf:指向存放待写入数据的缓冲区的指针
count:指定希望读出的字节数
函数返回值
成功:已写的字节数
出错:-1
在写普通文件时,写操作从文件的当前指针位置开始。
6. lseek()函数语法要点
每个打开文件都有一个与其相关联的“当前文件位移量”。它是一个非负整数,对应从文件开始处计算的字节数,通常,读、写操作都从当前文件位移量处开始,并使位移量增加所读或写的字节数。系统默认:当打开一个文件时,除非指定O_APPEND选择项,否则该位移量被设置为0。
所需头文件
#include
#include
函数原型:off_t lseek(int fd, off_t offset, int whence)
参数
fd:文件描述符
offset:偏移量,需要移动的距离,单位是字节,可正可负(向前移,向后移)
函数原型off_t lseek(int fd, off_t offset, int whence)
参数:
whence:基准位置
7. 实例基本功能:
从一个文件(源文件)中读取最后10KB数据并到另一个文件(目标文件);
在实例中源文件是以只读方式打开;
目标文件是以只写方式打开(可以是读写方式);
若目标文件不存在,可以创建并设置权限的初始值为644,即文件所有者可读可写,文件所属组和其他用户只能读。
/*将文件src_file中的后10个字节的数据拷贝到dest_file文件中去,前提是src_file中已经准备好了数据*/
#include
#include
#include
#include
#include
#include
#define BUFFER_SIZE 15 /* 每次读写缓存大小,影响运行效率*/
#define SRC_FILE_NAME "src_file" /* 源文件名*/
#define DEST_FILE_NAME "dest_file" /* 目标文件名文件名*/
#define OFFSET 10 /* 复制的数据大小*/
int main()
{
int src_file, dest_file;
unsigned char buff[BUFFER_SIZE];
int real_read_len;
/* 以只读方式打开源文件*/
src_file = open(SRC_FILE_NAME, O_RDONLY);
if (src_file < 0 )
{
printf("SRC_FILE Open error\n");
exit(1);
}
/* 以只写方式打开目标文件,若此文件不存在则创建该文件, 访问权限值为644 */
dest_file = open(DEST_FILE_NAME,O_WRONLY|O_CREAT,S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
if (dest_file < 0)
{
printf("DEST_FILE_NAME Open error\n");
exit(1);
}
/* 将源文件的读写指针移到最后10KB的起始位置*/
lseek(src_file, -OFFSET, SEEK_END);
/* 读取源文件的最后10KB数据并写到目标文件中,每次读写1KB */
while ((real_read_len = read(src_file, buff, sizeof(buff))) > 0)
{
write(dest_file, buff, real_read_len);
}
close(dest_file);
close(src_file);
return 0;
}
首先编写源文件,在源文件中输入一串字符:(大于10个字节)
在终端中编译运行源程序:在终端中使用cat命令输出目标文件中的内容:
打印变量real_read_len,显示的是10个字节:
读者可以看见,此处只从源文件拷贝了9个字节的内容到目标文件,我觉得应该是文件末尾的结束符eof占了一个字节,所以导致只显示了9个字节的数据,文件结束符eof为不可打印字符,未显示出来。
本人学识浅薄,如果大家知道其中的原因,还望不惜赐教。