欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

文件长度

程序员文章站 2022-03-11 14:50:01
...
与文件结构关系十分密切的 stat 结构中有个 st_size 成员,它表示以字节为单位的文件的长度,但这个字段只对普通文件、目录文件和符号链接有意义(FreeBSD 8.0、Mac OS X 10.6.8 和 Solaris 10 对管道也定义了文件长度,表示可从该管道中读到的字节数)。
对于普通文件,其长度可以是 0,在开始读这种文件时,将得到文件结束指示。
对于目录,文件长度通常是一个数(如 16 或 512)的整数倍。
对于符号链接,文件长度是在文件名中的实际字节数(注意:因为符号链接文件长度总是由 st_size 指示,所以它并不包含通常 C 语言用作名字结尾的 null 字节)。如下面的例子中,文件长度 7 就是路径名 usr/lib 的长度:
lrwxrwxrwx 1 root 7 Sep 25 07:14 lib -> usr/lib
对于含有空洞的文件(空洞是由所设置的偏移量超过文件尾端,并写入了某些数据后造成的),比如下列情况:

$ ls -l core
-rw-r--r-- 1 sar 8483248 Nov 18 12:18 core
$ du -s core
272 core # 这里一个字节块只有 512 个字节

根据 du 命令的输出,该文件所使用的磁盘空间总量是 139264 个字节,远小于 ls 命令的显示结果,所以它显然含有很多空洞。
对于没有写过的字节位置,read 函数读到的字节是 0。如果执行下面的命令,可以看出正常的 I/O 操作读整个文件长度:

$ wc -c core # 以字节为单位来统计
8483248 core

如果使用实用程序(如 cat)复制这个文件,那么所有这些空洞都会被填满,其中所有实际数据字节皆填写为 0。

$ cat core > core.copy
$ ls -l core*
-rw-r--r-- 1 sar 8483248 Nov 18 12:18 core
-rw-rw-r-- 1 sar 8483248 Nov 18 12.27 core.copy
$ du -s core*
272 core
16592 core.copy

从中可见,新文件所用的实际字节数是 8495104(512 * 16592),也并不等于 ls 命令显示的 8483248。这是因为文件系统还使用了若干块以存放指向实际数据的各个指针。
另外,前面说过,在打开文件时指定 O_TRUNC 这一标志,可将文件的长度截断为 0。实际上,存在两个专门的文件长度截断函数:

#include <unistd.h>

int truncate(const char *pathname, off_t length);
int ftruncate(int fd, off_t length);
/* 返回值:若成功,都返回 0;否则,都返回 -1 */

这两个函数都将一个现有文件长度截断为 length。如果文件以前的长度小于 length,那么新增的这部分数据将被读作 0(也就是可能创建了一个空洞)。