字符设备获取可写的长度


C获取文件的长度

在C中,如果要获取文件的长度,可以使用stat函数,如下所示:

// #include <sys/stat.h>
// #include <stdio.h>
struct stat st;
int ret = stat("test.txt", &st);
if (ret == -1)
{
    printf("File does not exist.\n");
    return 0;
}
printf("Size of file: %ld bytes.\n", st.st_size);

stat是一个系统调用,它的作用是获取文件的状态信息,包括文件的大小、文件的权限、文件的创建时间、文件的修改时间等等。如果文件不存在,stat函数会返回-1,同时设置errno的值为ENOENT。如果文件存在,stat函数会返回0,并且将文件的状态信息保存在st结构体中。

相比于stat函数,fstat函数可以获取文件描述符对应的文件的状态信息。如果文件描述符对应的是一个字符设备,那么fstat函数会返回-1,同时设置errno的值为ENOTTY。如果文件描述符对应的是一个普通文件,那么fstat函数会返回0,并且将文件的状态信息保存在st结构体中。

相比于lseek加上tell获取文件的长度,stat函数的优点是不需要打开文件,因此会更加高效。并且,可以获取到一些特殊的文件的长度,比如管道、套接字等。

字符设备获取可写的长度

在Linux中,字符设备的文件描述符对应的是一个字符设备文件,而不是一个普通文件。也就是字符设备并没有文件系统,也没有文件的元数据。在以前的内核实现中,对字符文件使用stat会返回-1,但是在新的内核实现中,对字符文件使用stat会返回0,并且将一些信息保存在st结构体中,这些信息中并不包括可写的长度。

为了获取字符设备的可写长度,需要用到ioctl函数。ioctl函数的作用是对设备进行控制,可以获取设备的状态信息,也可以设置设备的状态信息。ioctl函数的第一个参数是文件描述符,第二个参数是命令,第三个参数是参数。例子如下所示,该代码可以获取块设备的大小。

int fd = open("/dev/loop25", O_RDONLY);
size_t size = 0;
int ret = ioctl(fd, BLKGETSIZE64, &size);
assert(ret == 0);

Author: 蒋璋
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint polocy. If reproduced, please indicate source 蒋璋 !