大家好,这里是小缺,一名对嵌入式软件开发充满热情的探索者。在学习过程中,想到写一些文章,总结归纳所学的知识点,温故而知新。并将我的学习心得、实践经验和遇到的问题以及解决方案分享给大家,同时也希望能够从社区中学习到更多的知识和经验。今后,我会记录我在嵌入式软件开发道路上的点点滴滴。本篇文章我将向大家介绍文件描述符,一些常见系统调用IO函数,例如open、write、read、remove、close
一、 文件描述符
在Unix和类Unix操作系统中,文件描述符是一个非负整数,用于标识一个打开的文件或其它I/O对象。文件描述符是进程级别的,不同的进程可以拥有相同的文件描述符编号,但它们各自引用不同的文件或I/O对象。
当一个进程打开一个文件或创建一个新的文件时,操作系统会分配一个文件描述符给这个文件。这个文件描述符可以被用来对文件进行读取、写入、移动文件指针等操作。简单言之,如果要操作文件,那么就是对这个文件描述符的操作
当一个程序运行或者一个进程开启时,系统会自动创建三个文件描述符
标准输入(Standard Input):文件描述符编号为0。这个文件描述符通常与键盘输入关联,进程可以通过它来读取输入数据。
标准输出(Standard Output):文件描述符编号为1。这个文件描述符通常与屏幕输出关联,进程可以通过它来输出数据。
标准错误(Standard Error):文件描述符编号为2。这个文件描述符也与屏幕输出关联,但它用于输出错误信息。
我们要注意,当进程打开一个文件时,操作系统分配的文件描述符是按照一定顺序分配的,通常是按照进程当前已打开的文件描述符的最小空闲值来分配。这意味着如果进程已经打开了文件描述符0、1和2,那么下一个打开的文件将被分配文件描述符3,依此类推。
二、open函数
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h> //open函数所需头文件
int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode);
功能:打开或者创建一个文件,返回文件描述符
参数含义:
pathname:指定路径的文件名,不指定路径默认为当前路径
flags:标志位(标志位用于指定打开文件的方式)
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 读写
O_CREAT 文件不存在则创建,需要通过第三个参数设置文件权限
O_EXCL 一般与O_CREAT一起使用,标识如果文件存在则报错
O_TRUNC 如果文件存在则清空
O_APPEND 如果文件存在则追加
mode:这个参数在使用
O_CREAT
标志位时是必需的,它指定了文件的读、写和执行权限,以及文件的特殊属性,一般填入0644.返回值:
成功:文件描述符(int型)
失败:‐1
案例:
用只读的方式打开file.txt文件,将返回的文件描述符打印,如果open打开失败打印“fail to open”.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char const *argv[])
{
//使用open函数打开或者创建一个文件
int fd;
fd = open("file.txt", O_RDONLY);
if(fd == ‐1)
{
perror("fail to open");
return ‐1;
}
printf("fd = %d\n", fd);
return 0;
}
执行结果:
touch file .txt是创建一个名为file.txt的文件
三、close函数
#include <unistd.h>
int close(int fd);
功能:关闭一个文件描述符
参数:
fd:指定文件的文件描述符,open函数的返回值
返回值:
成功:0
失败:‐1
案例:
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int fd;
fd = open("file.txt", O_RDONLY);
if(fd == ‐1)
{
perror("fail to open");
return ‐1;
}
printf("fd = %d\n", fd);
//当不对文件进行任何操作时,就会关闭文件描述符
//使用close函数关闭文件描述符
//一旦关闭了文件描述符,就不能再通过原有的文件描述符对文件进行操作
close(fd);
return 0;
}
四、write函数
#include <unistd.h>
ssize_t write(int fd, const void *buf, size_t count);
功能:向文件写入数据
参数:
fd:指定的文件描述符
buf:要写入的数据
count:要写入的数据的长度
返回值:
成功:实际写入的字节数
失败:‐1
案例
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
//向文件写入数据
int fd;
//以只写的方式打开文件,如果文件不存在则创建,如果文件存在则清空
fd = open("file.txt", O_WRONLY | O_CREAT | O_TRUNC, 0664);
if(fd == ‐1)
{
perror("fail to open");
return ‐1;
}
//使用write函数向文件写入数据
ssize_t bytes;
if((bytes = write(fd, "hello world\n", 12)) == ‐1)
{
perror("fail to write");
return ‐1;
}
printf("bytes = %ld\n", bytes);
//这里只想文件中写了5个字节所以只会显示nihao
write(fd, "nihao beijing", 5);
//关闭文件描述符
close(fd);
return 0;
}
执行结果
cat是去看文件里面的内容
五、read函数
#include <unistd.h>
ssize_t read(int fd, void *buf, size_t count);
功能:从文件中读取数据
参数:
fd:指定的文件描述符
buf:保存读取到的数据
count:最大一次读取多少个字节
返回值:
成功:实际读取的字节数
失败:‐1
注意:如果读取到文件末尾,返回0
代码演示
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define N 64
int main(int argc, char const *argv[])
{
//使用read从文件中读取数据
int fd;
if((fd = open("test.txt", O_RDONLY | O_CREAT, 0664)) == ‐1)
{
perror("fail to open");
return ‐1;
}
//读取文件内容
char buf[N] = "";
ssize_t bytes;
#if 1
if((bytes = read(fd, buf, 32)) == ‐1)
//将文件的内容取32字节读取到buf中,读不到就打印fail to read
{
perror("fail to read");
return ‐1;
}
printf("buf = [%s]\n", buf);//打印buf中的内容
printf("bytes = %ld\n", bytes);//打印读取到的字节数
#endif
#if 0
//读取文件中的所有内容
while((bytes = read(fd, buf, 32)) != 0)
{
printf("buf = [%s]\n", buf);
printf("bytes = %ld\n", bytes);
}
#endif
//关闭文件描述符
close(fd);
return 0;
}
六、remove函数
#include <stdio.h>
int remove(const char *pathname);
功能:删除指定文件
参数:
pathname:包含路径的文件名
返回值:
成功返回0
失败返回‐1
#include <stdio.h>
int main(int argc, char const *argv[])
{
//使用remove函数删除文件
if(remove("./file.txt") == ‐1)
{
perror("fail to remove");
return ‐1;
}
printf("delete done\n");//成功删除会打印
return 0;
}
到这里这篇文章也就结束了,大家也可以自己去试一试,如果有什么错误,诚请指点。