Как надежно определить размер папки с помощью FileSystemObject.Size? - PullRequest
2 голосов
/ 23 апреля 2011

Пытаясь вычислить размер папки, которая может быть очень большой, я использовал FileSystemObject.Size:

#! perl

use strict;
use warnings;

use 5.10.0;

use File::Spec;
use Win32::OLE;

my $_fso;
sub folder_size {
  my($folder) = @_;

  $_fso = Win32::OLE->new("Scripting.FileSystemObject")
    unless defined $_fso;

  die "GetFolder $folder: $^E"
    unless defined(my $f = $_fso->GetFolder($folder));

  my $size = $f->Size;
  die "Size $folder: $^E" unless defined $size;

  $size;
}

В некоторых случаях folder_size возвращается нормально, но в других случаях вызов Size вызывает исключения. Вычисление размеров папок в C:\ с

my $root = "C:/";
opendir my $dh, $root or die "$0: opendir: $!";

while (defined(my $name = readdir $dh)) {
  next if $name eq "." || $name eq "..";
  my $folder = File::Spec->catdir($root, $name);
  next unless -d $folder;

  chomp(my $size = eval { folder_size $folder } // $@);
  print "$folder - $size\n";
}

Я получаю следующий вывод:

C:\$Recycle.Bin - Size C:\$Recycle.Bin: The resource loader failed to find MUI file at olesize line 22.
C:\boot - 17463020
C:\cygwin - 1835711453
C:\DELL - 133184282
C:\doctemp - 12811140
C:\Documents and Settings - Size C:\Documents and Settings: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Drivers - 180746384
C:\eclipse - 324690795
C:\EFI - 262144
C:\found.000 - Size C:\found.000: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\ghc - 1014658071
C:\gtk2hs - 138050118
C:\PerfLogs - Size C:\PerfLogs: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Perl - 115648300
C:\Program Files - Size C:\Program Files: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\ProgramData - Size C:\ProgramData: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Python25 - 83902423
C:\System Volume Information - Size C:\System Volume Information: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Users - Size C:\Users: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Virtual Machines - 5401825804
C:\Windows - Size C:\Windows: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\xampp - 408475320

Кажется, что, по крайней мере, частично проблема с разрешениями, потому что запуск кода от имени Администратора изменяет некоторые выходные данные (отмечены жирным шрифтом).

<b>C:\$Recycle.Bin - 2062958143</b>
C:\boot - 17463020
C:\cygwin - 1835711453
C:\DELL - 133184282
C:\doctemp - 12811140
C:\Documents and Settings - Size C:\Documents and Settings: The resource loader failed to find MUI file at olesize line 22.
C:\Drivers - 180746384
C:\eclipse - 324690795
C:\EFI - 262144
<b>C:\found.000 - 8950</b>
C:\ghc - 1014658071
C:\gtk2hs - 138050118
<b>C:\PerfLogs - 0</b>
C:\Perl - 115648300
<b>C:\Program Files - 10857194364</b>
C:\ProgramData - Size C:\ProgramData: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Python25 - 83902423
C:\System Volume Information - Size C:\System Volume Information: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Users - Size C:\Users: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\Virtual Machines - 5401825804
C:\Windows - Size C:\Windows: The resource loader cache doesn't have loaded MUI entry at olesize line 22.
C:\xampp - 408475320

Сообщение об ошибке MUI соответствует ERROR_MUI_FILE_NOT_FOUND.

Как мой код неверен?

Для контекста у меня нет требования использовать FileSystemObject. Другими подходами, которые я рассматривал, было удаление результата dir /s и суммирование размеров всех листьев в поддереве. Для больших каталогов вывод dir /s может быть огромным, и очистка всего поддерева - это служебная собака. Похоже, что проводник Windows всегда способен вычислить результат при достаточном времени, поэтому есть ли способ вызвать то, что он делает?

1 Ответ

0 голосов
/ 24 апреля 2011

Другой вариант - придерживаться чистого perl: Filesys :: DiskUsage делает то же самое. Однако я держу пари, что проблемы с разрешением останутся. По крайней мере, это должно быть лучше, чем очистка вывода dir /s.

Если честно, если Проводник работает с этими каталогами, когда вы не вошли в систему как администратор, для меня это похоже на проблему повышения привилегий в Explorer - очевидно, Explorer может обращаться к файловой системе, как если бы это был администратор, даже когда он не вошел в систему как таковой, поэтому, если вы можете загрузить собственную DLL-библиотеку в Explorer, у вас тоже может быть доступ администратора.

...