魔鬼在细节......对于初学者来说,有Unix设计的基本原则: 一切都是文件 ,很好 在这里解释 。
第二个是stat(2)电话给你 索引节点 存储在文件系统上的统计信息 设备专用文件 它的大小为零(想象它为 lstat(2) )。如果您有一个包含文件系统的块设备,则可以使用它获取有关它的信息 statfs(2) 要么 getfsstat(2) 要么 statvfs(2) 以独立于文件系统/设备的方式。
lstat(2)
statfs(2)
getfsstat(2)
statvfs(2)
处理特殊文件(通常驻留在/ dev中)一直是系统特定的,手册页面位于第4节。因此,如果您想直接操作设备,您应该阅读那里的具体信息。例如,在Linux中 man 4 hd 将向您展示如何以编程方式与IDE块设备进行交互。而 man 4 sd 将为您提供如何与scsi光盘等进行交互
man 4 hd
man 4 sd
第三,系统调用的功能不应该是不一致的 也不 他们的局限。
希望这有所帮助。
lseek 是C的骨干 fseek ,所以它有类似的语义,匹配 fseek - 与Unix API的其他领域完全脱节。出于明智的原因,你会期待 lseek 像文件处理一样行事 fseek ,和 fseek 是一个C库接口,它不是特定于Unix的。
lseek
fseek
stat 但是,它是特定于Unix的,并且有自己的特色。如果你考虑来源,这是一个合理的差异。当然问题是,C API具有非常弱的类型模型,因为C只能使真正的类型安全成为可能。
stat
为什么这很重要?因为,从根本上说,一个 seekable_size 和a file_object_size 是两个根本不同的概念,并且需要不同的类型 - 甚至C ++标准库也会出错。
但是在C ++和现代编译器中,它现在是一个完全无偿的遗留缺点,在C中实际上没有办法在不破坏性能和代码可读性的情况下有效地将整数包装成不兼容的类型。因此你最终得到了类似的东西 offs_t 要么 long 被用于完全不相容的概念。这是混淆的原因:仅仅因为你从文件相关函数中获得与大小相关的数字并不意味着该数字具有相同的含义。并且意义通常被捕获在类型中 - 唯一意义a long 天生就是“我,我是一个数字,你可以和我做数字事情”浓:(
offs_t
long
在Linux上,记录的获取可以打开的原始磁盘设备大小的方法是使用 BLKGETSIZE IOCTL。见 sd(4) 手册页。
BLKGETSIZE
sd(4)
请注意,这将返回设备的大小 行业 。您可能认为,对于以字节为单位的大小,您必须乘以返回的值 BLKSSZGET ioctl,但是 如果我正确地阅读源代码 ,无论如何,你实际上必须乘以512 BLKSSZGET 回报。
BLKSSZGET
“设备”的长度,如 /dev/sda 没有指定 POSIX struct stat :
/dev/sda
struct stat
off_t st_size For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. For a shared memory object, the length in bytes. For a typed memory object, the length in bytes. For other file types, the use of this field is unspecified.
所以POSIX不要求磁盘设备的“大小”。
Linux同样如此 没有指明 stat() 应返回磁盘设备的大小:
stat()
st_size 此字段给出文件的大小(如果它是常规的 文件 或以字节为单位的符号链接。符号链接的大小是 它包含的路径名的长度,没有终止 空字节。
st_size
此字段给出文件的大小(如果它是常规的 文件 或以字节为单位的符号链接。符号链接的大小是 它包含的路径名的长度,没有终止 空字节。