17.LINUX中的read函数
17.LINUX中的read函数
1.read函数的函数原型
#include <unistd.h>
ssize_t read(int fd,void *buf,size_t count);
函数原型为:ssize_t read(int fd, void *buf, size_t count);其中,fd为文件描述符;buf表示读出数据缓冲区地址;count表示读出的字节数。返回值:若读取成功,则返回读到的字节数;若失败,返回-1;若已达到文件尾,则返回0。 这个函数的功能是从文件中读取指定数量的字节到缓冲区中。如果读取成功,函数会返回实际读取到的字节数;如果读取失败,函数会返回-1;如果已经到达文件末尾,函数会返回0。
2.read函数应用实例
编写简单的read函数程序,使用gcc编译器编译。read函数程序如下所示:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int fd;
char buf[32] = { 0 };
//char类型的buf,设置为32;给其做清零操作
ssize_t ret;
//read函数的返回值是ssize_t类型的,现在给其定义一个返回值命名为ret
fd = open("a.c", O_RDWR);
//open"a.c文件",在之前open函数中已经创建了该文件
if (fd < 0)
{
printf("open is error\n");
return -1;
}
printf("fd is %d\n", fd);
ret = read(fd, buf, 32);
//fd是通过open这个函数调用获得的;第二个参数是地址,写为buf;
//第三个参数为要读取的字节数,这里选择写为32,与char buf[32]保持一致
//最后打印返回值 为何打印ret?因为如果读取成功的话会返回读取的字节数
//打印ret的值即可知道读取了多少字节 此处打开的是a.c 所以读取的时候会读取a.c里面的内容
//在ubuntu界面给a.c文件写入“hello readfunction!”
if (ret < 0)
{
printf("read is error\n");
return -2;
}
printf("buf is %s\n", buf);
printf("ret is %ld\n", ret);
close(fd);
return 0;
}
在ubuntu界面的运行结果命名为read为:
据char buf[32]={0}与ret=read(fd,buf,32);测试是否最大读取字节为32?
将a.c文件的内容写为:hello readfunction!hellohellohellohellohello
查看运行结果,如下:(最大读取字节数为32)
根据提供的代码和描述,以下是程序的行为:
- 当你使用
gcc read.c -o read
命令,你正在编译名为read.c
的源代码文件,并将生成的可执行文件命名为read
。 - 当你运行
./read
,你正在执行这个可执行文件。
在你的描述中,当你执行程序后,输出为:
fd is 3
buf is hello readfunction!
现在,我来解释这些输出:
-
fd is 3: 在UNIX和Linux系统中,当你打开一个文件,操作系统会为该文件提供一个文件描述符。文件描述符是一个非负整数。通常,描述符0、1和2分别代表标准输入、标准输出和标准错误输出。因此,当你首次在程序中打开一个文件,它通常会得到文件描述符3,这就解释了为什么输出是 "fd is 3"。
-
buf is hello readfunction!: 这是你从
a.c
文件中读取的内容。你的代码从该文件读取了最多32个字节的数据,然后将这些数据存储在buf
中。因为a.c
的内容是 "hello readfunction!",所以你的代码读取并显示了这个内容。
这段代码是一个简单的C程序,用于打开名为“a.c”的文件,从中读取最多32个字节的数据,然后显示读取到的数据和实际读取的字节数。接下来我会逐行解释代码的作用:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
上述头文件包含了程序中使用到的各种函数和数据类型的声明。
int main(int argc, char* argv[])
{
int fd;
char buf[32] = { 0 };
在主函数中,定义了文件描述符 fd
用于存储文件的引用,定义了一个32字节的字符数组 buf
用于存储从文件中读取的数据。
ssize_t ret;
定义一个 ssize_t
类型的变量 ret
,用于存储 read
函数的返回值。
fd = open("a.c", O_RDWR);
尝试以读写模式打开名为 "a.c" 的文件。成功打开的话,open
函数返回一个非负的文件描述符;否则返回-1。
if (fd < 0)
{
printf("open is error\n");
return -1;
}
检查文件是否成功打开。如果 fd
小于0,表示打开文件出错,并输出错误消息。
printf("fd is %d\n", fd);
打印文件描述符的值。
ret = read(fd, buf, 32);
从文件描述符 fd
指向的文件中读取最多32个字节的数据,并将读取的数据存放到 buf
中。
if (ret < 0)
{
printf("read is error\n");
return -2;
}
检查 read
函数是否成功。如果 ret
小于0,表示读取数据时出错,并输出错误消息。
printf("buf is %s\n", buf);
打印从文件中读取的数据。请注意,假设读取的数据是一个有效的字符串。
printf("ret is %ld\n", ret);
打印实际从文件中读取的字节数。
close(fd);
关闭文件描述符,释放与之相关联的资源。
return 0;
}
程序成功执行后返回0。
总的来说,这段代码展示了如何在C语言中使用 open
, read
, 和 close
函数进行文件操作。
3.说明
在man手册对于read函数的说明中提到:除去读取失败的情况,如果读取到文件的末尾,此时再读取时,返回值也会是0。
做一下测试,在刚才的C代码读取完成之后再加入一段读取操作。(将a.c文件的内容再回去“hello readfunction!”)
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int fd;
char buf[32] = { 0 };
//char类型的buf,设置为32;给其做清零操作
ssize_t ret;
//read函数的返回值是ssize_t类型的,现在给其定义一个返回值命名为ret
fd = open("a.c", O_RDWR);
//open"a.c文件",在之前open函数中已经创建了该文件
if (fd < 0)
{
printf("open is error\n");
return -1;
}
printf("fd is %d\n", fd);
ret = read(fd, buf, 32);
//fd是通过open这个函数调用获得的;第二个参数是地址,写为buf;
//第三个参数为要读取的字节数,这里选择写为32,与char buf[32]保持一致
//最后打印返回值 为何打印ret?因为如果读取成功的话会返回读取的字节数
//打印ret的值即可知道读取了多少字节 此处打开的是a.c 所以读取的时候会读取a.c里面的内容
//在ubuntu界面给a.c文件写入“hello readfunction!”
if (ret < 0)
{
printf("read is error\n");
return -2;
}
printf("buf is %s\n", buf);
printf("ret is %ld\n", ret);
ret = read(fd, buf, 32);
if (ret < 0)
{
printf("read is error\n");
return -2;
}
printf("buf is %s\n", buf);
printf("ret is %ld\n", ret);//二次执行read读取
close(fd);
return 0;
}
在ubuntu界面的运行结果命名为read1,结果如下:
4.总结
在此次编写的代码中,read函数如果调用成功的话,它返回的是实际读到的字节数;它如果返回的是0,表示它已经读到了文件的末尾;如果返回的是-1,表示读取出错。
参考资料: