究竟什么是"%~zI"扩展到FOR循环中的目录?

Кон*_*Ван 5 windows cmd batch-file filesize variable-expansion

来自FOR /?:

In addition, substitution of FOR variable references has been enhanced.
You can now use the following optional syntax:

    %~I         - expands %I removing any surrounding quotes (")
    %~fI        - expands %I to a fully qualified path name
    %~dI        - expands %I to a drive letter only
    %~pI        - expands %I to a path only
    %~nI        - expands %I to a file name only
    %~xI        - expands %I to a file extension only
    %~sI        - expanded path contains short names only
    %~aI        - expands %I to file attributes of file
    %~tI        - expands %I to date/time of file
    %~zI        - expands %I to size of file
    %~$PATH:I   - searches the directories listed in the PATH
                   environment variable and expands %I to the
                   fully qualified name of the first one found.
                   If the environment variable name is not
                   defined or the file is not found by the
                   search, then this modifier expands to the
                   empty string
Run Code Online (Sandbox Code Playgroud)

我已经运行Windows批处理脚本,并@echo %~aI %~fI ^<%~zI byte^(s^)^>FOR遍历目录循环(每个路径被存储在%I),并得到这个输出:

d--hs------ J:\$RECYCLE.BIN  <0 byte(s)>
d---------- J:\Multimedia  <4096 byte(s)>
dr--------- J:\-C-\……\Desktop  <12288 byte(s)>
dr--------- J:\-C-\……\Documents  <28672 byte(s)>
dr--------- J:\-C-\……\Downloads  <81920 byte(s)>
Run Code Online (Sandbox Code Playgroud)

上述目录的"大小"与其中的文件无关.它的"大小"究竟是什么意思%~zI?这是%I一个普通的文件,它的大小.但是如果%I是一个目录呢?我无法理解它.这真的没意义吗?

phu*_*clv 6

这是目录条目的消耗空间

每个目录实际上是一个包含其他文件和目录的特殊文件,因此它必须将该列表存储在某处,如果需要,还必须存储其他必要的元数据.某些文件系统将分配普通集群并将元数据存储在该数据区域中.

在NTFS中,小文件可以驻留在MFT条目中,这就是为什么你可以看到一些零字节文件夹,因为它不需要为目录元数据单独分配的块

您可以查看$I30并查看$INDEX_ALLOCATION

例如,这是我电脑的输出.相同的尺寸中可以看到$INDEX_ALLOCATION$I30输出

PS C:\> cmd /c "for /d %I in (*) do @echo %~aI %~fI  ^<%~zI byte^(s^)^>"
d---------- C:\ESD  <0 byte(s)>
d---------- C:\Intel  <0 byte(s)>
d---------- C:\PerfLogs  <0 byte(s)>
dr--------- C:\Program Files  <8192 byte(s)>
dr--------- C:\Program Files (x86)  <4096 byte(s)>
dr--------- C:\Users  <4096 byte(s)>
d---------- C:\Windows  <16384 byte(s)>
d---------- C:\Windows.old  <4096 byte(s)>

PS C:\> foreach ($f in ls -Attr Directory) {
>>     $fileLayout = (fsutil file layout $f) -join "`0"
>>     $result = (([regex]'\$I30.*?(?=Stream|$)').Matches($fileLayout)) -split "`0" | Select-String -Pattern '\$I30|  Size'
>>     echo "================================ $f"; $result
>> }
================================ ESD

$I30:$INDEX_ROOT
    Size                : 48
================================ Intel
$I30:$INDEX_ROOT
    Size                : 368
================================ PerfLogs
$I30:$INDEX_ROOT
    Size                : 48
================================ Program Files
$I30:$INDEX_ROOT
    Size                : 168
$I30:$INDEX_ALLOCATION
    Size                : 8,192
$I30:$BITMAP
    Size                : 8
================================ Program Files (x86)
$I30:$INDEX_ROOT
    Size                : 56
$I30:$INDEX_ALLOCATION
    Size                : 4,096
$I30:$BITMAP
    Size                : 8
================================ Users
$I30:$INDEX_ROOT
    Size                : 56
$I30:$INDEX_ALLOCATION
    Size                : 4,096
$I30:$BITMAP
    Size                : 8
================================ Windows
$I30:$INDEX_ROOT
    Size                : 432
$I30:$INDEX_ALLOCATION
    Size                : 16,384
$I30:$BITMAP
    Size                : 8
================================ Windows.old
$I30:$INDEX_ROOT
    Size                : 56
$I30:$INDEX_ALLOCATION
    Size                : 4,096
$I30:$BITMAP
    Size                : 8
Run Code Online (Sandbox Code Playgroud)

当显示的大小fsutil file layout <directory_path>不是目录中文件的总大小时,*nix上也会发生同样的事情: