我注意到当我使用open
+ lseek
查询设备的大小时,一切正常,但是当我对设备进行stat
时,得到的不是实际设备大小,而是零。该设备是干净的,没有任何文件系统,并且该设备的首字节以“1234567890ABC”之类的文本开头。怎么了?
代码:
#include <sys/stat.h>
#include <dirent.h>
bool
GetFileSize(const char* pPath, uint64_t& Size)
{
pPath = "/home/sw/.bashrc";
pPath = "/dev/sda";
struct stat buffer;
if (stat(pPath, &buffer))
{
printf("Failed to stat file. Error: %s. FilePath: %s\n", strerror(errno), pPath);
return false;
}
printf("File size by stat: %" PRIu64 " WTF?\n", buffer.st_size);
//
// Note: It's strange, but stat::st_size from the stat call is zero for devices
//
int File = open(pPath, O_RDONLY);
if (File < 0)
{
printf("Failed to open file. Error: %s. FilePath: %s\n", strerror(errno), pPath);
return false;
}
long off = lseek(File, 0, SEEK_END);
if (off == (off_t)-1)
{
printf("Failed to get file size. Error: %s. FilePath: %s\n", strerror(errno), pPath);
close(File);
return false;
}
close(File);
printf("File size by lseek: %" PRIu64 "\n", off);
fflush(stdout);
Size = off;
return true;
}
输出:
File size by stat: 0 Huh?
File size by lseek: 34359738368
如果我将stat用于常规文件,则一切正常(用“/dev/sda”注释掉):
File size by stat: 4019 Huh?
File size by lseek: 4019
最佳答案
细节在于魔鬼...对于初学者来说,Unix设计的基本原理是:一切都是文件,很好explained here。
第二个是stat(2)调用为您提供存储在文件系统中的设备专用文件的inode统计信息,该文件的大小为零(将其视为lstat(2)
)。如果您的块设备上有文件系统,则可以使用statfs(2)
或getfsstat(2)
或statvfs(2)
以与文件系统/设备无关的方式获取有关该文件的信息。
处理特殊文件(通常位于/dev中)始终是系统特定的,并且手册页位于第4节中。因此,如果您想直接操作设备,则应在此处详细阅读。例如,在Linux中,man 4 hd
将向您展示如何与IDE块设备进行编程交互。而man 4 sd
将为您提供如何与scsi光盘等进行交互的方式。
第三,系统调用不应在功能上或功能上与它们不一致。
希望这有所帮助。
关于c - 为什么stat::st_size 0 for devices but at the same time lseek defines the device size correctly?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55164462/