我想知道我的不同子目录的大小,所以我在SO和其他地方跟踪了Getting Directory sizes powershell和Display directory structure in powershell以及其他一些的指示。这些功能运行良好,除了我想知道一些部分同步的文件夹占用磁盘的空间(例如,我在Skydrive中有一个文件夹,只有一些子文件夹在线可用)。当我调用任一函数时,它们会报告文件夹的大小,就像它在磁盘中一样,而不是实际的磁盘使用情况。如果我右键单击该文件夹并检查其属性,我可以清楚地看到size
和size in disk
之间存在差异。
我尝试使用Sort-Object -Property Size
和Sort-Object -Property Length
切换到任一函数(主要基于Get-ChildItem
函数),但它们都返回大小而不是磁盘大小。
我想有一个简单的开关,只考虑实际的磁盘使用量,而不是总大小,但我完全失去了如何实现它。任何线索都非常感谢!
谢谢,
答案 0 :(得分:2)
磁盘大小是文件在驱动器上占用的实际大小,具体取决于群集大小(或分配单元),大多数时间是4KB,但不是所有时间。这取决于文件格式及其格式。
只要文件没有被压缩,就可以找出需要多少块的簇才能适合每个文件。请记住,如果文件小于群集大小,它将占用一个分配单元。
如果文件已压缩,则信息不易获取,需要通过API检索。
以下代码分为3个主要部分:
GetCompressedFileSizeAPI
的Type。此函数将检索文件磁盘上的压缩大小。$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
来源:
Understanding NTFS compression
Help querying files to return SIZE on DISK
Size of compressed files (in French)
How to get the actual size-on-disk of a file from PowerShell?
答案 1 :(得分:0)
出于某种原因,我在稀疏文件代码段中遇到了某些值是字符串而不是数字的错误。
然而,当我拿出&#34; 。$ _全名&#34;从下面
$sparsesize = ($files | %{
if ($_.length -lt $driveinfo.BlockSize -and $_.length -ne 0)
{
$driveinfo.BlockSize
}
else
{
$_.fullname
[FileInfo]::GetCompressedFileSize($_.fullname)
}
}|Measure -sum).sum
$sparsesize
并将其更改为
$sparsesize = ($files | %{
if ($_.length -lt $driveinfo.BlockSize -and $_.length -ne 0)
{
$driveinfo.BlockSize
}
else
{
[FileInfo]::GetCompressedFileSize($_.fullname)
}
}|Measure -sum).sum
$sparsesize
然后它返回一个数值。