第5章 基础文件操作
掌握文件操作比较重要的,作为嵌入式开发,需要理解文件的操作。 用到头文件是
#include“fcntl.h”
属于 POSIX(Portable Operating System Interface),是一个底层的系统调用,直接与操作系统交互。适合系统编程或需要直接控制底层文件操作的场景。
5.1 open 函数
系统调用 open 的作用是打开一个文件,并返回这个文件的描述符。
函数原型:
int open(const char *path, int oflags);
int open(const char *path, int oflags, mode_t mode );
参数说明:
path:准备打开的文件或设备名字。
oflags:指出要打开文件的访问模式。
O_RDONLY 【3 选 1】以只读方式打开
O_WRONLY 【3 选 1】以只写方式打开
O_RDWR 【3 选 1】以读写方式打开
O_APPEDN 【|可选】以追加方式打开
O_TRUNC 【|可选】把文件长度设为零,丢弃以后的内容。
O_CREAT 【|可选】如果需要,就按参数 mode 中给出的访问模式创建文件。
O_EXCL 【|可选】与 O_CREAT 一起调用,确保调用者创建出文件。使用这个模式可防止两个程序同时创建一个文件,如果文件已经存在,open 调用将失败。
mode:当使用 O_CREAT 标志的 open 来创建文件时,我们必须使用三个参数格式的 open 调用。
第三个参数 mode 是几个标志按位 OR 后得到的。
S_IRUSR:读权限,文件属主
S_IWUSR:写权限,文件属主
S_IXUSR:执行权限,文件属主
S_IRGRP:读权限,文件所属组
S_IWGRP:写权限,文件所属组
S_IXGRP:执行权限,文件所属组
S_IROTH:读权限,其他用户
S_IWOTH:写权限,其他用户
S_IXOTH:执行权限,其他用户
返回一个大于0的值,则成功,返回的是文件描述符。
返回一个等于0的值,则打开失败。
返回一个小于0的值,则出现错误,可以从错误errno中获取错误的状态。
5.2 close 函数
close系统调用用于“关闭”一个文件。文件描述符被释放,并能够重新使用。当一个进程终止时,内核自动关闭它所有打开的文件。很多程序都利用了这一功能而不显式地用close关闭文件。
函数的定义如下:
头文件:#include <unistd.h>
函数原型: int close(int fd);
参数: 文件描述符
函数返回值:close成功返回0,出错返回-1
5.3 read 函数
从文件描述符fd相关的文件中读取nbytes个字节的数据到buf中,返回实际读入的字节数。
头文件: #include <unistd.h>
函数原型: size_t read(int fd, void *buf, size_t nbytes);
fd:文件描述符,标识要读取的文件。如果为0,则从标准输入读数据。
buf:缓冲区,用来存储读入的数据。
nbytes:要读取的字符数。
size_t:返回值,返回成功读取的字符数,它可能会小于请求的字节数。-1表示出现错误。
5.4 write函数
将字符串buf中前nbytes个字节的数据写入与文件描述符fd关联的文件中,返回实际写入的字节数
函数的定义如下:
头文件: #include <unistd.h>
函数原型:size_t write(int fd, const void *buf, size_t nbytes);
参数说明:
fd:文件描述符,目标文件。例如:fd的值为1,就向标准输出写数据,
buf:待写入的字符串。
nbytes:要写入的字符数。
size_t:函数返回值,返回成功写入文件的字符数。-1表示出现错误。
5.5 lseek函数
对文件描述符fd指定文件的读写指针进行设置,也就是说,它可以设置文件的下一个读写位置。
具体有以下三个作用
- 调整文件读写位置:通过lseek函数,可以移动文件的读写指针到任意位置,无论是向前还是向后移动,这在进行随机访问文件时非常有用23。
- 计算文件大小:通过lseek函数,可以设置文件的读写位置到文件末尾,然后通过返回值(从文件开头到当前读写位置的长度)来获取文件的大小24。
- 作为文件拓展:在向文件末尾写入数据时,lseek函数可以用来扩展文件的大小,这在需要动态扩展文件时非常有用
#include <unistd.h>
#include <sys/types.h>
off_t lseek(int filedes, off_t offset, int whence);
off_set:参数用来指定位置,偏移量,表示从whence指定的位置开始移动的字节数。可以是正数(向前移动),负数(向后移动),或者0(在whence指定的位置。
whence:参数定义该偏移值的用法。
whence可以取下列值
SEEK_SET:offset是一个绝对位置
SEEK_CUR:offset是相对于当前位置的一个相对位置
SEEK_END:offset是相对于文件尾的一个相对位置
off_t:lseek返回从文件到文件指针被设置处的字节偏移,失败时返回-1.
参数offset的类型off_t是一个与具体实现有关的整数类型,它定义在sys/types.h中
偏移量,表示从whence指定的位置开始移动的字节数。可以是正数(向前移动),负数(向后移动),或者0(在whence指定的位置
5.6 参考代码
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
{
int fd;
char buf2[] = "hello world,today is beautiful"; //自定义读写用的缓冲区
char buf[100];
if((fd = open("file.txt",O_RDWR|O_CREAT|O_APPEND)) < 0 ) {//打开文件
perror("open file failed\n");
return -1;
}
else
printf("open file successful\n");
if(write(fd, buf2,strlen(buf2)) < 0 ){ //向文件中写入数据
perror("write file failed\n");
return -1;
}
else
printf("write file successful\n");
if(close(fd) < 0 ) { //关闭文件
perror("close file failed\n");
return -1;
}
else
printf("close file successful\n");
if(open("file.txt", O_RDWR) < 0 ) { //打开文件
perror("open file failed\n");
return -1;
}
else
printf("open file successful\n");
if( read(fd, buf,100) < 0 ){//读取文件中的数据
perror("read file failed\n");
return -1;
}else{
printf("read data:\n");
printf("%s\n",buf);//将读取的数据输出到控制台
}
if(close(fd) < 0) {
perror("close file failed\n");
return -1;
}else
printf("close file successful\n");
return 0;
}