如何在Windows命令提示符中检测NTFS压缩?

3
我希望能够检测脚本所在的文件夹中是否启用了Windows文件夹压缩。

请参见 https://superuser.com/questions/1069033/is-there-a-way-to-toggle-the-windows-compress-this-drive-command-through-a-com - StayOnTarget
3个回答

3
编辑:答案在命令行参数中。当然,使用所需文件夹名称替换“.”(=当前目录):

for /f "delims=" %I in ('dir /B /AD "." 2^>Nul') do @echo %~aI "%I"

%~aI 修改器返回一个符合文件属性常量的字符串,具体如下:

FILE_ATTRIBUTE_DIRECTORY     d-------- 
FILE_ATTRIBUTE_READONLY      -r------- 
FILE_ATTRIBUTE_ARCHIVE       --a------ 
FILE_ATTRIBUTE_HIDDEN        ---h----- 
FILE_ATTRIBUTE_SYSTEM        ----s---- 
FILE_ATTRIBUTE_COMPRESSED    -----c--- 
FILE_ATTRIBUTE_OFFLINE       ------o-- 
FILE_ATTRIBUTE_TEMPORARY     -------t- 
FILE_ATTRIBUTE_REPARSE_POINT --------l

我回答另一个问题的答案中,有一个脚本输出一个包含以下标题的csv文件(修改文件掩码以将输出缩小到合理大小):
@ECHO OFF
SETLOCAL enableextensions
> files\FoldersAndFilesWithAttributes.csv (
  rem csv header
  echo "d","r","a","h","s","c","o","t","l","file"
  rem csv lines
  for /f "delims=" %%I in ('
    dir /S /B /A "%~1*.*" 2^>Nul
                           ') do call :display "%%~aI" "%%I"
)

ENDLOCAL
goto :eof

:display
:: subroutine to display file attributes as csv line
:: %1 file attributes ---------
:: %2 file name
set "attr=%~1"
set "out="%attr:~0,1%""
set "out=%out%,"%attr:~1,1%""
set "out=%out%,"%attr:~2,1%""
set "out=%out%,"%attr:~3,1%""
set "out=%out%,"%attr:~4,1%""
set "out=%out%,"%attr:~5,1%""
set "out=%out%,"%attr:~6,1%""
set "out=%out%,"%attr:~7,1%""
set "out=%out%,"%attr:~8,1%""
set "out=%out:-=%"
echo %out%,"%~2"
goto :eof

要将单行输出限制在单个目录中,可以将dir命令的适当文件掩码与管道组合,并用findstr命令。例如,要获取当前目录的属性:

for /f "delims=" %I in ('dir /B /S /AD ".." 2^>Nul ^|findstr /I /R /C:"^%CD:\=\\%$"') do @echo %~aI "%~I"

输出 (:

D:\bat\compressed folder>for /f "delims=" %I in ('dir /B /S /AD ".." 2^>Nul ^|findstr /R /C:"^%CD:\=\\%$"') do @echo %~aI "%~I"
d----c----- "D:\bat\compressed folder"

D:\bat\compressed folder>cd ..

D:\bat>for /f "delims=" %I in ('dir /B /S /AD ".." 2^>Nul ^|findstr /R /C:"^%CD:\=\\%$"') do @echo %~aI "%~I"
d---------- "D:\bat"

D:\bat>

或者简单地使用for %I in (.) do @echo %~aI %~fI,输出结果相同。

获取当前目录及其内容的属性:

for /f "delims=" %I in ('dir /B /S /A ".." 2^>Nul ^|findstr /I /R /C:"^%CD:\=\\%"') do @echo %~aI "%~I"

输出:

D:\bat\compressed folder>for /f "delims=" %I in ('dir /B /S /A ".." 2^>Nul ^|findstr /I /R /C:"^%CD:\=\\%"') do @echo %~aI "%~I"
d----c----- "D:\bat\compressed folder"
d----c----- "D:\bat\compressed folder\Within compressed folder"
--a--c----- "D:\bat\compressed folder\Within compressed folder\xxx.csv"
--a--c----- "D:\bat\compressed folder\Within compressed folder\xxxx.csv"

D:\bat\compressed folder>

获取当前目录及其子文件夹的属性(不包括文件):

for /D /R %I in (.) do @echo %~aI %~fI

2
不适用于目录,并且在压缩文件夹中不会为我显示“c”。 - CodeCaster
1
天啊,这可真是黑魔法!有没有一种方法可以不用for循环来完成,或者仅限于一个单独的目录?我不想列出文件——可能有很多或者没有——我只想查看新创建的文件是否在当前目录中具有该属性。 - xtravar

1

compact 命令行实用程序...

显示或更改 NTFS 分区上文件或目录的压缩情况。 如果不带参数使用,compact 将显示当前目录及其包含的文件的压缩状态。

https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/compact

这是一个示例,展示了大量文件(全部未压缩)的一般格式。
C:\Windows
λ compact *.exe

 Listing C:\Windows\
 New files added to this directory will not be compressed.

    71168 :     71168 = 1.0 to 1   bfsvc.exe
    44544 :     44544 = 1.0 to 1   clspack.exe
  2871808 :   2871808 = 1.0 to 1   explorer.exe
   103424 :    103424 = 1.0 to 1   extrac32.exe
    15360 :     15360 = 1.0 to 1   fveupdate.exe
   733696 :    733696 = 1.0 to 1   HelpPane.exe
    16896 :     16896 = 1.0 to 1   hh.exe
   306688 :    306688 = 1.0 to 1   IsUninst.exe
   154112 :    154112 = 1.0 to 1   jview.exe
    19456 :     19456 = 1.0 to 1   keyhh.exe
   193536 :    193536 = 1.0 to 1   notepad.exe
   427008 :    427008 = 1.0 to 1   regedit.exe
    30720 :     30720 = 1.0 to 1   REGTLIB.EXE
    42496 :     42496 = 1.0 to 1   setdebug.exe
    67072 :     67072 = 1.0 to 1   splwow64.exe
  1372840 :   1372840 = 1.0 to 1   Sysmon.exe
    49680 :     49680 = 1.0 to 1   twunk_16.exe
    31232 :     31232 = 1.0 to 1   twunk_32.exe
    24168 :     24168 = 1.0 to 1   UnsignedThemesSvc.exe
   296960 :    296960 = 1.0 to 1   winhlp32.exe
   147456 :    147456 = 1.0 to 1   wjview.exe
    10240 :     10240 = 1.0 to 1   write.exe

Of 22 files within 1 directories
0 are compressed and 22 are not compressed.
7,030,560 total bytes of data are stored in 7,030,560 bytes.
The compression ratio is 1.0 to 1.

这是第二个示例,展示了样本压缩文件的输出结果:
λ compact test*.txt

 Listing C:\Users\chg0418\Documents\
 New files added to this directory will not be compressed.

   266240 :    180224 = 1.5 to 1 C test.txt
    29970 :     28672 = 1.0 to 1 C test2.txt

Of 2 files within 1 directories
2 are compressed and 0 are not compressed.
296,210 total bytes of data are stored in 208,896 bytes.
The compression ratio is 1.4 to 1.

0

我确认在"%v"替换变量的中间使用"~a"修饰符仅返回包含文件%v的文件夹的属性,而不是文件本身的属性...

要获取文件的实际压缩状态,请使用"COMPACT filanemes"显示其压缩比。

不幸的是,这并不能直接显示文件的压缩情况以及特定可执行文件(非可执行文件使用不同的方法)使用了哪种"WOFADK.SYS"方法(XPRESS4K、XPRESS8K、XPRESS16K或LZX)。NTFS本地压缩不用于可执行文件,而是使用WOF/WOFADK叠加驱动程序进行压缩(更多或更少地像重解析点,具有指示实际存储压缩数据的结构化数据存储,它可以在另一个文件中,例如WIM文件中,并且文件的页面片段的组织方式)。

WOF/WOFADK压缩的可执行文件在启用文件资源管理器中的此设置时不会显示为“蓝色”:蓝色用于普通数据文件(文本/日志、位图/图标、XML、HTML、源文件等)。 WOF可以在此基础上使用,并且内部使用标准隐藏文件,这些文件可能或可能不使用NTFS压缩本身。这些经过WOF压缩的文件在资源管理器中看起来好像没有被压缩,但是内部存储可能是稀疏的,如果WOF压缩的文件具有常见片段(例如大量共同数据的跨度),则它们将占用更少的空间,但是压缩是在内存页面大小边界上完成的。我想这是出于内核性能原因而进行的,以便WOF压缩可以避免跨越多个存储页面的片段,并且I/O然后减少,并且分页可以工作。

NTFS文件压缩可以更有效,但它不允许原地压缩,并且对于非只读文件的扩展性不好:它仅适用于一次性压缩整个文件和顺序读取访问。WOF压缩允许随机访问,但代价是更适度的压缩比。WOF压缩还可以将多个具有内部链接到公共存储池的可执行文件压缩(这就是Windows映像的WIM文件非常小的原因,约为4GB,而其扩展大小将大约为4倍:WOF压缩在WIM文件中是全局的,并且最适合只读文件)。 WOF压缩显然也用于VM的VHDX格式;两者都在小物理空间上创建虚拟大存储空间,但只能进行只读操作的随机访问;在WOF / WIM / VHDX中进行写操作可能会很慢或会降低压缩比(后台工作程序可以重新优化存储,如果没有更多的修改待处理并且足够的空闲时间已经过去而没有写访问)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接