一、文件描述符
在linux系统内核中,所有打开的文件都是由文件描述符来表示。当打开或者创建文件时,系统会返回一个文件描述符,当向文件写入数据的时候,需要传递一个描述符给系统。 对于每一个应用程序,打开的文件描述符都是由小到大递增,从 0 开始。而且对于每个程序来说,系统都预定义了三个文件描述符 0 、 1 和 2,其中 0 是标准输入,1 是标准输出,2 是标准错误输出,它们在unistd.h中分别被定义为:STDIN_FILENO、
STDOUT_FILENO和
STDERR_FILENO。
二、函数介绍
2.1 open 函数
2.1.1 函数说明
open()函数用于打开文件。
2.1.2 函数原语
1 |
int open(const char *pathname , int oflag, .../*, mode_t mode */); |
2.1.3 头文件
1 2 3 |
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> |
2.1.4 oflag 的取值
必选选项,三选一:
O_RDONLY
:只读方式打开O_WRONLY
:只写方式打开O_RDWR
:读写方式打开
常用的可选选项:
O_APPEND
:以追加方式打开,仅在文件以读属性打开时有效O_CREAT
:如果文件不存在则创建,此时需要设置第三个参数 mode 表示文件的属性O_EXCL
:和 O_CREAT 一起使用,如果文件存在则报错,用于使用原子操作创建文件O_TRUNC
:只读或只写方式打开文件时,把文件清空
2.1.5 返回值
成功返回文件描述符,失败返回-1,并设置errno。
2.2 creat 函数
2.2.1 函数说明
creat()函数用于创建一个文件。
2.2.2 函数原语
1 |
int creat(const char *pathname, mode_t mode) ; |
2.2.3 头文件
1 2 3 |
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> |
2.2.4 参数说明
pathname
:要创建的目录地址mode
:文件的权限属性,会受到 umask 的限制
2.2.5 返回值
成功返回文件描述符,失败返回-1,并设置errno;等同于open(pathname, O_WRONLY|OCREAT|O_TRUNC, mode)
2.3 close 函数
2.3.1 函数说明
close()函数用于关闭一个已经打开的文件描述符。
2.3.2 函数原语
1 |
int close(int filedes); |
2.3.3 头文件
1 |
#include <unistd.h> |
2.3.4 返回值
成功返回0,失败返回-1。
2.4 lseek 函数
2.4.1 函数说明
每个文件被打开后都有一个文件指针指向当前的文件位置,如果打开时没有指定O_APPEND选项的话,指针的默认位置是在文件的开头,会随着文件的读取和写入而变化,lseek()函数用于设置当前指针的位置。
2.4.2 函数原语
1 |
off_t lseek(int filedes, off_to ffset, int whence) ; |
2.4.3 头文件
1 2 |
#include <sys/types.h> #include <unistd.h> |
2.4.4 参数说明
whence表示设置指针的位置,off_to是一个整数,表示相对于whence的偏移量。
whence选项:
SEEK_SET
:设置指针位置为文件开头+offset 个字节SEEK_CUR
:设置指针位置为当前位置+offset 个字节SEEK_END
:设置指针位置为文件末尾+offset 个字节
2.4.5 返回值
成功之后返回文件指针的位置,失败返回-1 。
2.5 read 函数
2.5.1 函数说明
read()函数用于向文件写入数据。
2.5.2 函数原语
1 |
ssize_t read(int filedes, void *buff, size_t nbytes) ; |
2.5.3 头文件
1 |
#include <unistd.h> |
2.5.4 参数说明
fileds
:文件描述符buff
:用于读取数据的字符串缓冲区nbytes
:读取的字节数量
2.5.5 返回值
成功返回读到的字节数,失败返回-1,读到文件末尾返回0。
2.6 write 函数
2.6.1 说明
write()函数用来写数据到文件
2.6.2 函数原语
1 |
ssize_t write(int filedes, const void *buff, size_t nbytes) ; |
2.6.3 头文件
1 |
#include <unistd.h> |
2.6.4 参数说明
filedes
:文件描述符buff
:要写入的数据nbytes
:写入的数据大小
2.6.5 返回值
成功返回写入的字节数,失败返回-1。
三、示例代码
3.1 写文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
int main(){
int fd;
char buff[1024] = "HelloWorld
HelloMaQian
";
ssize_t len;
fd = open("test.txt", O_WRONLY | O_CREAT | O_TRUNC, 0777); //以只读方式打开,如果文件不存在则创建,存在就清空
if (fd == -1){
perror("open file error!");
return 0;
}else{
len = write(fd, buff, strlen(buff)); //写入字符
if (len < 0){
perror("Write file error");
}else{
printf("Write %d byte data to file
", (int)len);
}
}
close(fd);
return 0;
}
编译运行:
ma@ma:/data/code/cpp/file$ gcc file.c -o app # 编译
ma@ma:/data/code/cpp/file$ ./app # 运行
Write 23 byte data to file
ma@ma:/data/code/cpp/file$ cat test.txt # 查看文件内容
HelloWorld
HelloMaQian
ma@ma:/data/code/cpp/file$ ls -l test.txt # 查看文件属性
-rwxrwxr-x 1 ma ma 23 11月 5 20:50 test.txt
ma@ma:/data/code/cpp/file$ umask # 文件权限0777 & ~0002 = 775
0002
3.1 读文件
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
int main(){
int fd, ok;
char buff[1024] = {0};
ssize_t len;
fd = open("test.txt", O_RDONLY);
if (fd == -1){
perror("open file error!");
return 0;
}else{
len = read(fd, buff, 10); // 读取10字节
if (len < 0){
perror("Read file error");
}else{
printf("Read %d byte data:%s
----------
", (int)len, buff);
}
ok = lseek(fd, 0, SEEK_SET); //文件指针设置到文件开头
if (ok == -1){
perror("Set file seek error");
}else{
len = read(fd, buff, sizeof(buff)); //读1024个字节文件
if (len < 0){
perror("Read file error");
}else{
printf("Read %d byte data:%s
", (int)len, buff);
}
}
}
close(fd);
return 0;
}
运行结果如下:
ma@ma:/data/code/cpp/file$ gcc file.c -o app
ma@ma:/data/code/cpp/file$ ./app
Read 10 byte data:HelloWorld
----------
Read 23 byte data:HelloWorld
HelloMaQian
评论