为什么 ls 跟 du 看起来的大小不一样?

在查看同一个文件的大小的时候,可以用 ls 或者 du 指令。细心的使用者有时候会发现它们显示出来的大小是不一样的,比如:
在这里插入图片描述
造成这种现象主要有两个原因

1、du 跟 ls 默认情况下显示的大小含义不同

先要准备个知识:在文件系统中,对磁盘的操作并不会具体到字节,而是操作文件块(Block)。

想象一下如果不分块而是直接按字节读取(实际上会退化成按扇区逻辑块,这里为了方便,用字节来举例),那么,要么就按照连续存储而导致碎片问题,要么就只能按照字节粒度来对硬盘发出指令读取而导致效率问题。

块(Block)的提出可以折中上面的两个优缺点。自己最明显的缺点是会造成一定的磁盘浪费,比如文件系统规定块大小是 4K,那么存储 1Byte 的文件也需要占用一个块, 4K 的磁盘空间。不过这个缺点在存储单价越来越低的时代下,对比优点就不足为道了,因此几乎所有现代的文件系统都已经采用了此种策略。

Linux 系统下的 EXT4 文件系统默认 Block 大小是 4K,Windows 下 NTFS 的 Block 叫 Cluster(簇),其实也是一个意思,默认大小一般也是 4K(如果总大小更大比如超过 16T,默认策略也会变化,变得更大等等)。

回到 du 跟 ls 上,du 默认显示出来的含义,是实际的磁盘占用,所以上面的 config.js 是 4k(占了一个 Block),而 ls 默认显示的是文件实际的大小,也就是 2.3k(不够一个 Block)。

当然 ls 也可以通过参数来改变显示的含义,加上 -s 参数即可显示实际占用了。如下图:
在这里插入图片描述
Windows 也能感受到这种差异。对文件进行右键即可看到两种不同的大小。
在这里插入图片描述

2、稀疏文件的存在

稀疏文件的稀疏,类似于稀疏矩阵的稀疏。也就是中间有大量的 0 (空洞)。

稀疏文件其实就是对有大量的0的文件的文件系统级压缩。可以这么不严谨地理解:对于有100个0的文件,00000…0000 ,如果是稀疏文件格式,直接表示为 100x0 。

目前 Windows 跟 Linux 都有对稀疏文件的支持,macOS 在 2016年开始好像也升级了支持。

Windows 下创建稀疏文件参考:稀疏文件文档

Linux 下,可以用 dd 指令:

[admin@Test ~]$ dd if=/dev/null of=mysparse seek=1G count=0
记录了0+0 的读入
记录了0+0 的写出
0字节(0 B)已复制,0.000725152 秒,0.0 kB/秒
[admin@Test ~]$ du -h mysparse 
0	mysparse

也可以用C写入:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
 
int main(int argc,char *argv[])
{
    if(argc  < 2)
    {
        printf("输入错误,请重新输入!");
    }
    //打开文件
    int fw = open(argv[1],O_WRONLY | O_CREAT,0664);
    if(fw<0)
    {
    	perror("open error");
    	return -1;
    }
    //操作文件
    lseek(fw,1024*1024*1024,SEEK_SET);
    write(fw,"\0",1);
    //关闭文件
    close(fw);
    return 0;
}

执行

sparse mysparse

即可生成 mysparse 空洞文件。上面两种方式都用了 seek 方法,也就是文件操作指针偏移。这样的操作会让文件系统识别文件为空洞文件(中间跳过了数据进行写入)。

空洞文件的用处很多,比如说在用迅雷下载的时候,可以立即开辟出指定大小的文件。这样多线程下载文件的不同部位的时候再慢慢写入就可以了。而如果没有空洞文件的设定,就只能一点点下载、追加。

另外还有在块设备文件里的应用,也非常经典。参考写的另一篇文章:PVE存储

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值