Размер на диске — это фактический размер, занимаемый вашими файлами на диске, в зависимости от размера кластера (или единицы распределения), который в большинстве случаев составляет 4 КБ, но не всегда. Это зависит от формата файла и от того, как он был отформатирован.
Пока файлы не сжаты, нужно выяснить, сколько фрагментов кластеров необходимо для размещения каждого файла. Имейте в виду, что если файл меньше размера кластера, он займет одну единицу распределения.
Если файл сжат, информацию нелегко получить, и ее необходимо получить через API.
Следующий код разделен на 3 основных раздела:
- Он определяет тип, используемый для доступа к функции
GetCompressedFileSizeAPI
в kernel.dll. Эта функция будет получать сжатый размер файла на диске.
- Он использует WMI для определения размера кластера для данного
$path
- Он вычисляет размер на диске для файлов в папке и подпапках
$path
в зависимости от того, сжат файл или нет.
Обратите внимание, что вызов Get-ChildItem
использует переключатель -force
, чтобы убедиться, что мы также извлекаем скрытые и системные файлы.
Я не уверен, что этот код будет работать со Skydrive, поэтому вам может потребоваться изменить часть WMI.
$path = '.\'
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
public class FileInfo
{
[DllImport("kernel32.dll", SetLastError=true, EntryPoint="GetCompressedFileSize")]
static extern uint GetCompressedFileSizeAPI(string lpFileName, out uint lpFileSizeHigh);
public static ulong GetCompressedFileSize(string strFileName)
{
uint intHigh;
uint intLow;
intLow = GetCompressedFileSizeAPI(strFileName, out intHigh);
int intError = Marshal.GetLastWin32Error();
if (intHigh == 0 && intLow == 0xFFFFFFFF && intError != 0)
throw new Win32Exception(intError);
else
return ((ulong)intHigh << 32) + intLow;
}
}
"@
$files = Get-ChildItem $path -Recurse -force | where {$_.PSIsContainer -eq $false}
$drive = [string]$files[0].PSdrive+':'
$wql = "SELECT Blocksize FROM Win32_Volume where DriveLetter='$drive'"
$driveinfo = Get-WmiObject -Query $wql -ComputerName '.'
$sizeondisk = ($files | %{
if ($_.Attributes -like "*compressed*")
{
if ($_.length -lt $driveinfo.BlockSize -and $_.length -ne 0)
{
$driveinfo.BlockSize
}
else
{
[FileInfo]::GetCompressedFileSize($_.fullname)
}
}
else
{
if ($_.length -lt $driveinfo.BlockSize -and $_.length -ne 0)
{
$driveinfo.BlockSize
}
else
{
([math]::ceiling($_.length/$driveinfo.BlockSize))*$driveinfo.BlockSize
}
}
}|Measure -sum).sum
$sizeondisk
ОБНОВЛЕНИЕ для разреженных файлов:
Посмотрим, работает ли эта версия с разреженными файлами, добавим этот блок кода в конец предыдущего кода, все остальное оставим прежним:
$sparsesize = ($files | %{
if ($_.length -lt $driveinfo.BlockSize -and $_.length -ne 0)
{
$driveinfo.BlockSize
}
else
{
$_.fullname
[FileInfo]::GetCompressedFileSize($_.fullname)
}
}|Measure -sum).sum
$sparsesize
Источники:
Общие сведения о сжатии NTFS
Помощь в запросе файлов для возврата SIZE на DISK
Размер сжатых файлов (на французском языке)
Как получить фактический размер -на диск файла из PowerShell?
Размер кластера по умолчанию для NTFS, FAT и exFAT
person
Micky Balladelli
schedule
15.12.2014