为什么用ls和du显示出来的文件大小有差别?
曾经有几次,我用ls和du查看一个文件的大小,发现二者显示出来的大小并不一致,例如:
bl@d3:~/test/sparse_file$ ls -l fs.img -rw-r--r-- 1 bl bl 1073741824 2012-02-17 05:09 fs.img
bl@d3:~/test/sparse_file$ du -sh fs.img 0 fs.img
这里ls显示出fs.img的大小是1073741824字节(1GB),而du显示出fs.img的大小是0。
原来一直没有深究这个问题,今天特来补上。
造成这二者不同的原因主要有两点:
- 稀疏文件(sparse file)
- ls和du显示出的size有不同的含义
先来看一下稀疏文件。稀疏文件只文件中有“洞”(hole)的文件,例如有C写一个创建有“洞”的文件:
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char *argv[]) { int fd = open("sparse.file", O_RDWR|O_CREAT); lseek(fd, 1024, SEEK_CUR); write(fd, "\0", 1); return 0; }
从这个文件可以看出,创建一个有“洞”的文件主要是用lseek移动文件指针超过文件末尾,然后write,这样就形成了一个“洞”。
用Shell也可以创建稀疏文件:
$ dd if=/dev/zero of=sparse_file.img bs=1M seek=1024 count=0
0+0 records in
0+0 records out
使用稀疏文件的优点如下(Wikipedia上的原文):
The advantage of sparse files is that storage is only allocated when actually needed: disk space is saved, and large files can be created even if there is insufficient free space on the file system.
即稀疏文件中的“洞”可以不占存储空间。
再来看一下ls和du输出的文件大小的含义(Wikipedia上的原文):
The du command which prints the occupied space, while ls print the apparent size。
换句话说,ls显示文件的“逻辑上”的size,而du显示文件“物理上”的size,即du显示的size是文件在硬盘上占据了多少个block计算出来的。举个例子:
bl@d3:~/test/sparse_file$ echo -n 1 > 1B.txt
bl@d3:~/test/sparse_file$ ls -l 1B.txt
-rw-r--r-- 1 bl bl 1 2012-02-19 05:17 1B.txt
bl@dl3:~/test/sparse_file$ du -h 1B.txt
4.0K 1B.txt
这里我们先创建一个文件1B.txt,大小是一个字节,ls显示出的size就是1Byte,而1B.txt这个文件在硬盘上会占用N个 block,然后根据每个block的大小计算出来的。这里之所以用了N,而不是一个具体的数字,是因为隐藏在幕后的细节还很多,例如Fragment size,我们以后再讨论。
当然,上述这些都是ls和du的缺省行为,ls和du分别提供了不同参数来改变这些行为。比如ls的-s选项(print the allocated size of each file, in blocks)和du的--apparent-size选项(print apparent sizes, rather than disk usage; although the apparent size is usually smaller, it may be larger due to holes in (`sparse') files, internal fragmentation, indirect blocks, and the like)。
此外,对于拷贝稀疏文件,cp缺省情况下会做一些优化,以加快拷贝的速度。例如:
strace cp fs.img fs.img.copy >log 2>&1
打开log文件,我们发现cp命令只是read和lseek,并没有write。
stat("fs.img.copy", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 stat("fs.img", {st_mode=S_IFREG|0644, st_size=1073741824, ...}) = 0 stat("fs.img.copy", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 open("fs.img", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=1073741824, ...}) = 0 open("fs.img.copy", O_WRONLY|O_TRUNC) = 4 fstat(4, {st_mode=S_IFREG|0644, st_size=0, ...}) = 0 mmap(NULL, 532480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f90df965000 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 524288) = 524288 lseek(4, 524288, SEEK_CUR) = 524288 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 524288) = 524288 lseek(4, 524288, SEEK_CUR) = 1048576 read(3, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 524288) = 524288 lseek(4, 524288, SEEK_CUR) = 1572864
这和cp的关于sparse的选项有关,看cp的manpage:
By default, sparse SOURCE files are detected by a crude heuristic and the corresponding DEST file is made sparse as well. That is the behavior selected by --sparse=auto. Specify --sparse=always to create a sparse DEST file whenever the SOURCE file contains a long enough sequence of zero bytes. Use --sparse=never to inhibit creation of sparse files.
看了一下cp的源代码,发现每次read之后,cp会判断读到的内容是不是都是0,如果是就只lseek而不write。
当然对于sparse文件的处理,对于用户都是透明的。
转载自: http://www.cnblogs.com/coldplayerest/archive/2012/02/19/2358098.html
相关推荐
ls 命令用来以 K、M、G 为单位查看文件大小。例如,使用以下命令可以查看当前目录下的文件大小: ls -lh ls 命令也可以用来查看文件的详细信息,例如,使用以下命令可以查看文件的权限、所有者、群组、大小、修改...
* ls:显示文件大小 * 组合使用的方式 + ls -al:显示详细信息和所有文件 + ls -dl:只看当前目录的详细信息 + ls -alh:显示详细信息和所有文件的大小 ls 命令列举出来的信息的首字母代表着不同的含义: * d:...
今天,我们将学习如何使用 Linux 命令来清空和删除指定大小的大文件。 一、查找大文件 在 Linux 系统中,查找大文件可以使用 find 命令。find 命令可以根据文件的大小、修改时间、权限等属性来查找文件。例如,要...
* -b 参数:显示目录或文件大小时,以 byte 为单位。 * -k 参数:以 KB 为单位。 * -m 参数:以 MB 为单位。 * -h 参数:自动以 K、M、G 为单位。 * -S 参数:显示指定目录的大小时,并不含其子目录的大小。 * -L ...
`grep`用于在文件中搜索特定字符串,`find`根据指定条件查找文件,`du`和`df`分别显示文件大小和磁盘空间使用情况。 4. **权限与所有权**:Linux采用读(r)、写(w)、执行(x)的三权分立模式,每种文件都有属主...
安装Cygwin后,你可以使用`ncurses`版本的`du`和`df`命令来查看Linux文件大小。 - **Grafana + Telegraf + InfluxDB**:这是一个流行的监控堆栈,可以用来收集和展示各种数据,包括Linux系统的文件大小。Telegraf...
4. **磁盘空间管理**:学习如何查看和管理磁盘空间,包括查看磁盘使用情况(如`df`命令)、文件大小(如`du`命令)以及释放空间的方法。 5. **文件索引和I/O性能**:理解文件系统的索引结构,如inode(在Unix/Linux...
可以使用 `ls -sh *` 或 `du -sh *` 命令查看文件大小。 文件时间 文件时间是文件最后一次更改的时间,可以使用 `ls -l` 命令查看文件时间。 文件或者目录名称 文件或者目录名称是文件或者目录的唯一标识符,...
操作系统大作业 Windows API编写部分文件操作, 共支持13条命令的小型模拟... -du: 显示特定目录的大小 -catfile:显示多个文件或连接两个文件到第三个文件或将两个文件附加到第三个文件中 -f: 查找指定的文件
`ls`命令是我们常用的查看目录内容的工具,但正如描述中提到的,当我们使用`ls -lh`查看目录大小时,它显示的通常是4KB,这实际上是目录元数据的大小,而不是实际占用磁盘空间的内容总和。为了获取目录的实际大小,...
三、查看文件大小 Linux系统中,还可以使用ls命令来查看文件的大小。基本语法为:ls [options] [file] 其中,options是可选参数,file是要查看的文件。 ls命令的常用参数: * -l:以长格式输出文件信息。 * -h...
例如,`df`命令用于显示磁盘空间使用情况,`du`命令可以检查目录和文件的大小,`fsck`是用于检查和修复文件系统错误的工具,而`mkfs.ext4`则用于创建新的ext4文件系统。 博文链接虽然无法直接访问,但根据常规博客...
此外,还有其他命令可用于查询硬盘大小,如`lsfs -c -k`,它可以显示文件系统大小、已用空间等信息,单位为KB。 以上就是AIX系统中文件系统使用率高时的基本查询和处理思路。在实际运维中,还需要结合具体情况,如...
查看文件属性有多种方法,且这些方法中偏向不同,具体如下: 1,ls ls -a 查看所有文件 ... 您可能感兴趣的文章:Linux du命令查看文件夹大小并按降序排列Linux系统下如何查看及修改文件读写权限
例如,`du -sh *`显示当前目录下所有文件和目录的大小(以人类可读的格式)。 16. **df**:查看磁盘空间使用情况。 17. **chmod**:更改文件或目录的权限。例如,`chmod 755 file.sh`为文件设置可执行权限。 18. ...
ls(list)列表显示目录的文件以及子目录 l (long)以长格式显示文件和目录的列表 -a 显示所有的子目录和文件的信息 -d 显示目录本身的属性,常与-l 同时使用 -h 人性化的方式显示出目录的大小,常与-l 同时使用 -R ...
了解了这些基本概念后,我们可以通过`df`和`du`命令查看磁盘空间使用情况,`ls`命令列出目录内容,`find`命令搜索文件,以及`mount`和`umount`命令进行挂载和卸载操作。 在实际应用中,理解Linux文件系统的这些细节...
`du -sh *`显示当前目录所有文件的大小(单位为K、M、G)。 17. **df**:查看磁盘空间使用情况。`df -h`以人性化单位显示磁盘总空间和剩余空间。 这些基本命令构成了Linux系统管理的基础,熟练掌握它们能帮助你在...
ls:列出当前目录下的文件和目录。 ls -l:以长格式列出信息。 ls -a:显示所有文件,包括隐藏文件(以.开头的文件)。 mkdir:创建目录。 mkdir 目录名:在当前目录下创建新目录。 mkdir -p 目录名/子目录名:递归...