Linux文件目录大小详解

学无止境,遇到一个知识遗漏点,这里转载记录一下。

介绍

在Ubuntu上,发现大部分目录大小都是4096,不论目录包含内容多少,即使空的

root@s:~# mkdir a
root@s:~# ll
total 124
drwx------ 10 root root  4096 Jan 30 11:25 ./
drwxr-xr-x 23 root root  4096 Jan 18 17:57 ../
drwxr-xr-x  2 root root  4096 Jan 30 11:25 a/

这里有解释,这里记录一下实验。
一般情况下,HDD磁盘最小的管理单位是扇区(Sector,也叫Unit或者Block),扇区的大小是512Bytes,但Linux一次I/O是8个扇区即4096Bytes,因此Linux(准确的说是ext2/ext3等文件系统)存取文件的最小单位即使4096Bytes(=8个Blocks)(Windows的NTFS好像是1K即2个Blocks)

一般目录大小

目录是特殊文件,OS初始分配8个Blocks,且size也即是4096Bytes,这与普通文件(Regular file)不同,普通文件的size是给予文件内容计算的实际值,但是目录实际占用的磁盘空间总是4096的倍数

root@s:~/a# ll
total 8
drwxr-xr-x  2 root root 4096 Jan 30 14:16 ./
drwx------ 10 root root 4096 Jan 30 13:08 ../
root@s:~/a# stat ./
  File: './'
  Size: 4096        Blocks: 8          IO Block: 4096   directory
Device: fc00h/64512d    Inode: 11534348    Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:16:36.871365855 +0800
Modify: 2018-01-30 14:16:35.563360060 +0800
Change: 2018-01-30 14:16:35.563360060 +0800
 Birth: -

可以看出,空目录,目录的大小也是4096。

root@s:~/a# for i in `seq 1 1000`; do touch file$i; done
root@s:~/a# time ll
total 36
drwxr-xr-x  2 root root 28672 Jan 30 14:21 ./
drwx------ 10 root root  4096 Jan 30 13:08 ../
-rw-r--r--  1 root root     0 Jan 30 14:21 file1
-rw-r--r--  1 root root     0 Jan 30 14:21 file10
...
-rw-r--r--  1 root root     0 Jan 30 14:21 file999
root@s:~/a# stat ./
  File: './'
  Size: 28672       Blocks: 64         IO Block: 4096   directory
Device: fc00h/64512d    Inode: 11534348    Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:21:46.632874068 +0800
Modify: 2018-01-30 14:21:23.088755232 +0800
Change: 2018-01-30 14:21:23.088755232 +0800
 Birth: -

创建了1000个文件后,目录占用64个Blocks(32768Bytes),大小28672,得出2点结论:
1,目录的大小随着目录内容变动
2,目录的大小并不总是等于目录占用磁盘空间(本例是64个Blocks)的大小

删除文件后的目录大小

root@s:~/a# rm file*
root@s:~/a# ll
total 36
drwxr-xr-x  2 root root 28672 Jan 30 14:29 ./
drwx------ 10 root root  4096 Jan 30 13:08 ../
root@s:~/a# stat ./
  File: './'
  Size: 28672       Blocks: 64         IO Block: 4096   directory
Device: fc00h/64512d    Inode: 11534348    Links: 2
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:29:32.914860654 +0800
Modify: 2018-01-30 14:29:31.614855200 +0800
Change: 2018-01-30 14:29:31.614855200 +0800
 Birth: -

目录的size增大后,即使目录内容清空,目录大小以及所占磁盘空间并不相应减小。

普通文件大小

来看看普通文件怎么样

root@s:~/a# touch file
root@s:~/a# ll
total 36
drwxr-xr-x  2 root root 28672 Jan 30 14:31 ./
drwx------ 10 root root  4096 Jan 30 13:08 ../
-rw-r--r--  1 root root     0 Jan 30 14:31 file
root@s:~/a# stat file 
  File: 'file'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fc00h/64512d    Inode: 11534353    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:31:23.039323153 +0800
Modify: 2018-01-30 14:31:23.039323153 +0800
Change: 2018-01-30 14:31:23.039323153 +0800
 Birth: -
root@s:~/a# echo -n a >> file
root@s:~/a# stat file
  File: 'file'
  Size: 1           Blocks: 8          IO Block: 4096   regular file
Device: fc00h/64512d    Inode: 11534353    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:31:23.039323153 +0800
Modify: 2018-01-30 14:32:05.955503631 +0800
Change: 2018-01-30 14:32:05.955503631 +0800
 Birth: -

空文件大小为0,磁盘空间为0。

文件只包含一个字符(1Byte),大小为1Bytes,磁盘占用8Blocks。

root@s:~/a# for i in `seq 1 4095`; do echo -n a >> file; done
root@s:~/a# stat file
  File: 'file'
  Size: 4096        Blocks: 8          IO Block: 4096   regular file
Device: fc00h/64512d    Inode: 11534353    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:31:23.039323153 +0800
Modify: 2018-01-30 14:34:50.472196602 +0800
Change: 2018-01-30 14:34:50.472196602 +0800
 Birth: -

字符增加到4096个,size变为4096,磁盘占用任然是8Blocks。

root@s:~/a# echo -n a >> file
root@s:~/a# stat file 
  File: 'file'
  Size: 4097        Blocks: 16         IO Block: 4096   regular file
Device: fc00h/64512d    Inode: 11534353    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:31:23.039323153 +0800
Modify: 2018-01-30 14:36:06.176516024 +0800
Change: 2018-01-30 14:36:06.176516024 +0800
 Birth: -

在增加一个字符,size变为4097,而磁盘占用变为16个Blocks了

root@s:~/a# echo a > file
root@s:~/a# stat file 
  File: 'file'
  Size: 2           Blocks: 8          IO Block: 4096   regular file
Device: fc00h/64512d    Inode: 11534353    Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2018-01-30 14:31:23.039323153 +0800
Modify: 2018-01-30 14:37:22.348837733 +0800
Change: 2018-01-30 14:37:22.348837733 +0800
 Birth: -

文件内容缩小,size变小,占用空间也变小了

上面只是在ext2/ext3上实验的,而不同的文件系统表现是不一样的,比如这里解释

      而现在支持AF的磁盘扇区大小已是4096Bytes了,因为扇区之前间隔空间,所以理论上磁盘空间浪费减少了,而且正好与现行的I/O Block相等,所以应用程序如果以4096为单位读写的话,应该是性能最优的。有一点注意,支持AF的磁盘分区在现行Linux安装过程容易造成分区开始不对齐,而这会导致读写性能下降(我理解是,本来只要一个I/O,由于没对齐,跨扇区,导致多个I/O),这里有解释

root@compute10:~# fdisk -l
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
Disklabel type: dos
Disk identifier: 0x27f39080

Device     Boot   Start        End    Sectors  Size Id Type
/dev/sda1  *       2048     999423     997376  487M 83 Linux
/dev/sda2       1001470 1953523711 1952522242  931G  5 Extended
/dev/sda5       1001472 1953523711 1952522240  931G 8e Linux LVM

Partition 2 does not start on physical sector boundary.

上述参数解释看这里

 

发布了120 篇原创文章 · 获赞 125 · 访问量 107万+

猜你喜欢

转载自blog.csdn.net/yangyangye/article/details/103262245
今日推荐