`
hongtoushizi
  • 浏览: 358405 次
  • 性别: Icon_minigender_1
  • 来自: 天津
社区版块
存档分类
最新评论

为什么用ls和du显示出来的文件大小有差别?

阅读更多

为什么用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

分享到:
评论

相关推荐

    操作系统实验-文件系统

    操作系统大作业 Windows API编写部分文件操作, 共支持13条命令的小型模拟... -du: 显示特定目录的大小  -catfile:显示多个文件或连接两个文件到第三个文件或将两个文件附加到第三个文件中  -f: 查找指定的文件

    linux 查看文件的属性(ls,lsattr,file,stat)实例详解

    查看文件属性有多种方法,且这些方法中偏向不同,具体如下: 1,ls  ls -a 查看所有文件 ... 您可能感兴趣的文章:Linux du命令查看文件夹大小并按降序排列Linux系统下如何查看及修改文件读写权限

    linux基本操作命令 ls du touch mkdir cp mv which find cat more less head tail |(管道) wc grep gzip tar

    ls(list)列表显示目录的文件以及子目录 l (long)以长格式显示文件和目录的列表 -a 显示所有的子目录和文件的信息 -d 显示目录本身的属性,常与-l 同时使用 -h 人性化的方式显示出目录的大小,常与-l 同时使用 -R ...

    Linux系统目录大小通过du命令获取实例

    使用过 Linux 系统的小伙伴都知道应该都知道, Linux 系统下的 ls 命令通常被我们用来查看文件目录的内容,但是不知道大家有没有细心留意,ls 命令所显示出来的每一个目录的大小竟然都只有 4 KB ? $ ls -lh | grep...

    操作系统课程设计:Linux系统管理实践与进程通信实现.doc

    ls -l 显示目录下所有文件的许可权、拥有者、文件大小、修改时间及名称 ls -lg 同上 ls -R 显示出该目录及其子目录下的文件 注:ls与其它命令搭配使用可以生出很多技巧(最简单的如"ls -l " more"),更多用法请输入ls ...

    coreutils-8.32.tar.gz

    改变和显示终端行的设置 sum 显示指定文件的校验和及块数 sync 刷新文件系统缓冲区,使磁盘和内存的数据同步。 tac 逆向显示指定的文件,最后一行在最前。 tail 显示每个指定文件的最后几行(默认是10)。 ...

    linux第二章实验讲解.mp4

    -size 查找文件大小 +10m大于10m -10m小于 -type 查找文件类型:f文件 d目录 b ,c设备文件 -a 多个条件同时满足 -o 其中一个条件满足即可 例子: find /boot/ -size +1024k -a -name "vmlinuz*" find /boot/ -...

    hadoop命令

    -du(s) &lt;path&gt; //显示目录中所有文件大小 -count[-q] &lt;path&gt; //显示目录中文件数量 -mv &lt;src&gt; &lt;dst&gt; //移动多个文件到目标目录 -cp &lt;src&gt; &lt;dst&gt; //复制多个文件到目标目录 -rm(r) //删除文件(夹) -put &lt;localsrc&gt; ...

    glob-size:获取文件总大小

    请考虑关注该项目的作者 ,并考虑为该项目以显示您的 :red_heart: 和支持。 安装 使用安装: $ npm install --save glob-size 这类似于UNIX du命令(例如,尝试du -sh * ),但是具有JavaScript API。 这可以用于...

    UbuntuChina12

    5.2.1 使用ls命令显示文件 列表 108 5.2.2 利用通配符显示文件 110 5.2.3 显示隐藏文件 111 5.2.4 递归地列出文件 112 5.3 显示文件内容 113 5.3.1 使用cat命令显示文件 113 5.3.2 使用more命令分页显示 文件 113 ...

    Linux基本命令的使用

    • ls -l 列出文件详细信息 l(list) • ls -a 列出当前目录下所有文件及目录,包括隐藏的 a(all) • mkdir 创建目录 • rmdir 命令删除目录 • cd /var 切换目录 • rm -r 递归删除,可删除子目录及文件 • rm -f ...

    Ubuntu权威指南(2/2)

    5.2.1 使用ls命令显示文件 列表 108 5.2.2 利用通配符显示文件 110 5.2.3 显示隐藏文件 111 5.2.4 递归地列出文件 112 5.3 显示文件内容 113 5.3.1 使用cat命令显示文件 113 5.3.2 使用more命令分页显示 文件 113 ...

    Ubuntu权威指南(1/2)

    5.2.1 使用ls命令显示文件 列表 108 5.2.2 利用通配符显示文件 110 5.2.3 显示隐藏文件 111 5.2.4 递归地列出文件 112 5.3 显示文件内容 113 5.3.1 使用cat命令显示文件 113 5.3.2 使用more命令分页显示 文件 113 ...

    Linux操作系统基础教程

    五.Linux操作系统上有什么应用?.....................................................................................4 六.在那里可以找到讨论区?..........................................................

    java大数据内容_2HDFS

    -du(s) &lt;path&gt; // 显示目录中所有文件大小 -count[-q] &lt;path&gt; // 显示目录中文件数量 -mv &lt;src&gt; &lt;dst&gt; // 移动多个文件到目标目录 -cp &lt;src&gt; &lt;dst&gt; // 复制多个文件到目标目录 -rm(r) // 删除文件(夹) -mkdir ...

    unix实验报告.doc

    比较whoami 和who am i显示的结果区别,熟练使用cat、cd、chmod、ls、cp、ln、df、ps等命令。 2. 用vi编辑器,先在用户主目录中创建文件,编辑文件。并作统计文件大小,重新 编辑文件。字符串替换等工作 3. 用find...

    Linux指令一周通 (技术图书大系).azw3

    文件格式为azw3,文字版本,可以用kindle阅读,PC端可以用calibre,可以转成epub所有手机阅读软件都支持,对手机的排版支持还不错. 内容目录 第1天 文本操作指令 1.1 ar 指令:创建、修改或从档案文件中提取文件 1.2 ...

    linux.chm文档

    du -sk * | sort -rn 以容量大小为依据依次显示文件和目录的大小 rpm -q -a --qf '{SIZE}t%{NAME}n' | sort -k1,1n 以大小为依据依次显示已安装的rpm包所使用的空间 (fedora, redhat类系统) dpkg-query -W -f='${...

    xilinx FPGA(XC6SLX9)+SDRAM+AD7829多通道数据采集板AD设计硬件原理图+PCB文件.zip

    xilinx FPGA(XC6SLX9)+SDRAM+AD7829多通道数据采集板AD设计硬件原理图+PCB文件,4层板设计,大小为239*232mm,ALTIUIM设计的工程文件,可以做为你的学习设计参考。2片AD7829实现了10路数据采集,采集率可以达到2M,...

    Linux命令笔记

    du [选项][目录或文件] //统计目录或文件大小 df和du命令的区别 fsck [选项] 分区设备文件名 //文件系统修复命令 dumpe2fs 分区设备文件名 //显示磁盘状态命令 3:挂载命令 mount [选项] 设备文件名 挂载点 4:...

Global site tag (gtag.js) - Google Analytics