saber - obtener informacion de un archivo c#
Obtenga el tamaño del archivo en el disco (4)
Creo que será así:
double ifileLength = (finfo.Length / 1048576); //return file size in MB ....
Todavía estoy haciendo algunas pruebas para esto, para obtener una confirmación.
var length = new System.IO.FileInfo(path).Length;
Esto le da el tamaño lógico del archivo, no el tamaño en el disco.
Deseo obtener el tamaño de un archivo en el disco en C # (preferiblemente sin interoperabilidad ) como lo informaría el Explorador de Windows.
Debe dar el tamaño correcto, incluso para:
- Un archivo comprimido
- Un archivo disperso
- Un archivo fragmentado
De acuerdo con los foros sociales de MSDN:
El tamaño en el disco debe ser la suma del tamaño de los clústeres que almacenan el archivo:
http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvcs/thread/85bf76ac-a254-41d4-a3d7-e7803c8d9bc3
Necesitarás sumergirte en P/Invoke para encontrar el tamaño del cluster; GetDiskFreeSpace () lo devuelve.
Consulte Cómo obtener el tamaño en el disco de un archivo en C # .
Pero tenga en cuenta el hecho de que esto no funcionará en NTFS cuando la compresión está activada.
El código anterior no funciona correctamente en los sistemas basados en Windows Server 2008 o 2008 R2 o Windows 7 y Windows Vista, ya que el tamaño del clúster siempre es cero (GetDiskFreeSpaceW y GetDiskFreeSpace devuelven -1 incluso con UAC desactivado). Aquí está el código modificado que funciona.
DO#
public static long GetFileSizeOnDisk(string file)
{
FileInfo info = new FileInfo(file);
uint clusterSize;
using(var searcher = new ManagementObjectSearcher("select BlockSize,NumberOfBlocks from Win32_Volume WHERE DriveLetter = ''" + info.Directory.Root.FullName.TrimEnd(''//') + "''") {
clusterSize = (uint)(((ManagementObject)(searcher.Get().First()))["BlockSize"]);
}
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);
VB.NET
Private Function GetFileSizeOnDisk(file As String) As Decimal
Dim info As New FileInfo(file)
Dim blockSize As UInt64 = 0
Dim clusterSize As UInteger
Dim searcher As New ManagementObjectSearcher( _
"select BlockSize,NumberOfBlocks from Win32_Volume WHERE DriveLetter = ''" + _
info.Directory.Root.FullName.TrimEnd("/") + _
"''")
For Each vi As ManagementObject In searcher.[Get]()
blockSize = vi("BlockSize")
Exit For
Next
searcher.Dispose()
clusterSize = blockSize
Dim hosize As UInteger
Dim losize As UInteger = GetCompressedFileSizeW(file, hosize)
Dim size As Long
size = CLng(hosize) << 32 Or losize
Dim bytes As Decimal = ((size + clusterSize - 1) / clusterSize) * clusterSize
Return CDec(bytes) / 1024
End Function
<DllImport("kernel32.dll")> _
Private Shared Function GetCompressedFileSizeW( _
<[In](), MarshalAs(UnmanagedType.LPWStr)> lpFileName As String, _
<Out(), MarshalAs(UnmanagedType.U4)> lpFileSizeHigh As UInteger) _
As UInteger
End Function
Esto usa GetCompressedFileSize, como se sugirió ho1, así como GetDiskFreeSpace, como sugirió PaulStack; sin embargo, usa P / Invoke. Lo he probado solo para archivos comprimidos, y sospecho que no funciona para archivos fragmentados.
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);