Cela utilise GetCompressedFileSize, comme suggéré, ainsi que GetDiskFreeSpace, comme PaulStack suggéré, cependant, il utilise P/Invoke. Je l'ai testé uniquement pour les fichiers compressés, et je suppose que cela ne fonctionne pas pour les fichiers fragmentés.
public static long GetFileSizeOnDisk(string file)
{
FileInfo info = new FileInfo(file);
uint dummy, sectorsPerCluster, bytesPerSector;
int result = GetDiskFreeSpaceW(info.Directory.Root.FullName, out sectorsPerCluster, out bytesPerSector, out dummy, out dummy);
if (result == 0) throw new Win32Exception();
uint clusterSize = sectorsPerCluster * bytesPerSector;
uint hosize;
uint losize = GetCompressedFileSizeW(file, out hosize);
long size;
size = (long)hosize << 32 | losize;
return ((size + clusterSize - 1)/clusterSize) * clusterSize;
}
[DllImport("kernel32.dll")]
static extern uint GetCompressedFileSizeW([In, MarshalAs(UnmanagedType.LPWStr)] string lpFileName,
[Out, MarshalAs(UnmanagedType.U4)] out uint lpFileSizeHigh);
[DllImport("kernel32.dll", SetLastError = true, PreserveSig = true)]
static extern int GetDiskFreeSpaceW([In, MarshalAs(UnmanagedType.LPWStr)] string lpRootPathName,
out uint lpSectorsPerCluster, out uint lpBytesPerSector, out uint lpNumberOfFreeClusters,
out uint lpTotalNumberOfClusters);
êtes-vous sûr que c'est correct if (resultat == 0) throw new Win32Exception (resultat); – Simon
Le bit 'if (result == 0)' est correct (voir [msdn] (http://msdn.microsoft.com/fr-fr/library/aa364935.aspx)), mais vous avez raison de dire que je suis en utilisant le mauvais constructeur. Je vais le réparer maintenant. – margnus1
'FileInfo.Directory.Root' n'a pas l'air de pouvoir gérer n'importe quel type de liens de système de fichiers. Donc, il ne fonctionne que sur les lettres de lecteur locales classiques sans liens symboliques/hardlinks/points de jonction ou tout ce que NTFS a à offrir. – ygoe