Использование System.Drawing.Image для Export-Csv с $ imageFile.Width и $ _. Fullname - PullRequest
0 голосов
/ 13 марта 2012

Интересно, есть ли лучший способ написать этот скрипт для сбора размеров изображения и путей к файлам. Сценарий отлично работает на каталогах малого и среднего размера, но я не уверен, что возможно более 100 000 файлов / папок.

Measure-Command {

[Void][System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll")

$path = "\\servername.corp.company.com\top_directory"

$data = Get-ChildItem -Recurse $path | % {
 $imageFile = [System.Drawing.Image]::FromFile($_.FullName) ;
 New-Object PSObject -Property @{
 name = $_.Name
 fullname = $_.Fullname
 width = $imageFile.Width
 height = $imageFile.Height
 length = $_.Length
 }
 }
 $data | Where-Object {$_.width -eq 500 -or $_.width -eq 250 -or $_.width -eq 1250  } |

Export-Csv \\servername.corp.company.com\top_directory\some_directory\log_file.csv -NoTypeInformation } 

На самом деле я сейчас не использую фильтр Where-Object.

При запуске вышеуказанного скрипта в удаленном каталоге с помощью appx. 20000 файлов + папок скрипт занимает ок. 26 минут, прежде чем создавать .csv.

Я запускаю сценарий из Powershell V2 ISE в Windows 7 и считаю, что удаленный сервер находится в Windows Server 2003.

Будет ли запуск сценария напрямую с удаленного сервера быстрее?

Является ли процесс изучения CSV медленным, так как все данные собираются в «кэш» перед записью в CSV?

Если бы мне нужно было пройти только 20 000 файлов, я бы подождал 26 минут, но 500 000 файлов и папок - это долгое ожидание.

Я тестирую описанный ниже метод, поскольку думаю, что моя настоящая проблема не в скорости, а в хранении слишком большого количества данных в памяти. Спасибо за сообщение от Джорджа Говарта за это и PoSherLife за лучший скрипт - http://powershellcommunity.org/tabid/54/aft/4844/Default.aspx

Measure-Command {
[System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") 

"Name|SizeInBytes|Width|Height|FullName" >> C:\Users\fcool\Documents\JPGInfo.txt  

$path = "C:\Users\fcool\Documents" 
$images = Get-ChildItem -Recurse $path -Include *.jpg 

foreach ($image in $images) 
{ 
$name = $image.Name 
$length = $image.Length 
$imageFile = [System.Drawing.Image]::FromFile($image.FullName) 
$width = $imageFile.Width 
$height = $imageFile.Height
$FullName = $image.Fullname 

"$name|$length|$width|$height|$FullName" >> C:\Users\fcool\Documents\JPGInfo.txt  

$imageFile.Dispose() 
}
}

Есть ли риск / потеря производительности при запуске этих сценариев для файловых типов не-образных?

когда я не исключаю не изображения, я получаю эту ошибку:

Exception calling "FromFile" with "1" argument(s): "Out of memory." 
At C:\scripts\directory_contents_IMAGE_DIMS_ALT_method.ps1:13 char:46 
+ $imageFile = [System.Drawing.Image]::FromFile <<<< ($image.FullName) 
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException 
+ FullyQualifiedErrorId : DotNetMethodException 

спасибо за любой совет! и еще раз спасибо Джорджу Говарту и PoSherLife за сценарии!

1 Ответ

1 голос
/ 13 марта 2012

Использование -Filter с Get-ChildItem намного быстрее, чем -Include, однако вы можете применить только одну строку фильтра.Так что если вы хотите использовать только * .jpg, вы можете использовать фильтр.В моем тестировании использование фильтра было почти в 5 раз быстрее, чем включение.

Get-ChildItem -Recurse \\server\Photos -Filter *.jpg | % {
    $image = [System.Drawing.Image]::FromFile($_.FullName)
    if ($image.width -eq 500 -or $image.width -eq 250 -or $image.width -eq 1250) {
        New-Object PSObject -Property @{
            name = $_.Name
            fullname = $_.Fullname
            width = $image.Width
            height = $image.Height
            length = $_.Length
        }
    }
} | Export-Csv 'C:\log.csv' -NoTypeInformation
...