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);