Desidero riprodurre il comportamento esposto in Windows Explorer -> Finestra di dialogo Proprietà -> Pagina di proprietà generale per qualsiasi file specificato. Nello specifico voglio riprodurre il valore esatto del campo "Dimensione su disco".Come interrogare le informazioni sul file "Dimensioni su disco"?
risposta
Come altri hanno già detto, è necessario utilizzare GetFileInformationByHandleEx
, ma sembra che sia necessario utilizzare FILE_ID_BOTH_DIR_INFO. Le informazioni desiderate vengono restituite nel membro AllocationSize
. Secondo il link qui sopra,
AllocationSize Contiene il valore che specifica la quantità di spazio allocato per il file, in byte. Questo valore è solitamente un multiplo del settore o delle dimensioni del cluster del dispositivo fisico sottostante.
Questo sembra fornire le informazioni Size on Disk
.
Non ho trovato una traduzione Delphi della struttura FILE_ID_BOTH_DIR_INFO
. La difficoltà sembra essere l'ultimo membro, WCHAR FileName[1]
, che viene descritto come:
FileName [1]
Contiene il primo carattere della stringa nome del file. Questo è seguito in memoria dal resto della stringa.
Non sono sicuro di come sarebbe stato gestito in Delphi.
Vista + solo in base ai documenti. – kobik
In realtà, no. C'è una nota che dice che è disponibile su XP, nella sezione File Header: WinBase.h (include Windows.h); FileExtd.h su Windows Server 2003 e ** Windows XP **, con una libreria da collegare, quindi è possibile creare una DLL wrapper in C++ Builder e quindi chiamarla tramite tale wrapper. –
Oppure qualsiasi compilatore C o C++, ad es.i compilatori MS distribuiti nel Platform SDK –
è possibile utilizzare la funzione di GetFileInformationByHandleEx per ottenere FILE_COMPRESSION_INFO struttura, il suo campo CompressedFileSize
è il valore necessario (lo stesso restituito da GetCompressedFileSize
).
Anche se si avverte che l'utilizzo di questo su XP non è banale –
Ora sono completamente perplesso. FILE_COMPRESSION_INFO restituito dalla chiamata riuscita viene riempito con tutti gli zeri. Tuttavia, ho finalmente capito cosa è insolito con il file offensivo, aggiornando la domanda. – OnTheFly
@ user539484: cosa succede se si passa FILE_STANDARD_INFO e quindi leggere l'AllocationSize? Quando fallisce, prova FILE_STREAM_INFO e leggi StreamAllocationSize. Funziona solo su Vista e versioni successive. –
Raymond Chen L'articolo su Windows Confidential descrive come viene calcolato tale valore. Gli stati dei paragrafi più pertinenti:
La dimensione della misurazione del disco è più complicata. Se l'unità supporta la compressione (come riportato dal flag FILE_FILE_COMPRESSION restituito dalla funzione GetVolumeInformation) e il file è compresso o sparse (FILE_ATTRIBUTE_COMPRESSED, FILE_ATTRIBUTE_SPARSE_FILE), la dimensione su disco per un file è il valore riportato dalla funzione GetCompressedFileSize. Questo riporta la dimensione compressa del file (se compressa) o la dimensione del file meno le parti che sono state disimpegnate e logicamente trattate come zero (se sparse). Se il file non è né compresso né sparse, la Dimensione su disco è la dimensione del file riportata dalla funzione FindFirstFile arrotondata al cluster più vicino.
Pubblicare una routine in base all'estratto di David dell'articolo di Raymond. Sentiti libero di migliorarlo!
uses
System.SysUtils, Windows;
function GetClusterSize(Drive: String): integer;
var
SectorsPerCluster, BytesPerSector, dummy: Cardinal;
begin
SectorsPerCluster := 0;
BytesPerSector := 0;
GetDiskFreeSpace(PChar(Drive), SectorsPerCluster, BytesPerSector, dummy, dummy);
Result := SectorsPerCluster * BytesPerSector;
end;
function FindSizeOnDisk(Drive: String; AFilename: string): Int64;
var
VolumeSerialNumber: DWORD;
MaximumComponentLength: DWORD;
FileSystemFlags: DWORD;
HighSize: DWORD;
FRec: TSearchRec;
AClusterSize: integer;
AFileSize, n: Int64;
begin
Result := 0;
Drive := IncludeTrailingPathDelimiter(ExtractFileDrive(Drive));
GetVolumeInformation(PChar(Drive), nil, 0, @VolumeSerialNumber,
MaximumComponentLength, FileSystemFlags, nil, 0);
if ((FileSystemFlags AND FILE_FILE_COMPRESSION) <> 0) AND
((FileSystemFlags AND (FILE_VOLUME_IS_COMPRESSED OR
FILE_SUPPORTS_SPARSE_FILES)) <> 0) then
begin // Compressed or Sparse disk
Result := GetCompressedFileSize(PChar(AFilename), @HighSize);
// Not sure if this is correct on a sparse disk ??
end
else
begin
if (System.SysUtils.FindFirst(AFilename, faAnyFile, FRec) = 0) then
begin
AFileSize := FRec.Size;
AClusterSize := GetClusterSize(Drive);
n := AFileSize mod AClusterSize;
if n > 0 then // Round up to nearest cluster size
Result := AFileSize + (AClusterSize - n)
else
Result := AFileSize;
System.SysUtils.FindClose(FRec);
end;
end;
end;
Dal GetCompressedFileSize
restituirà la dimensione effettiva sia normale/compressa/Ricambi file di qualsiasi tipo volume, è possibile fare affidamento su questa funzione per restituire il File Size on Disk
(Esplora risorse di Windows è la visualizzazione di questo valore come fattore di volumi Dimensione Cluster), e ottenere il File Size
utilizzando la funzione GetFileSize
.
Dalla documentazione MSDN su GetCompressedFileSize
:
Se il file non si trova su un volume che supporta la compressione o file sparsi, o se il file non è compresso o di un file sparse, il valore ottenuto è la dimensione effettiva del file, uguale al valore restituito da una chiamata a GetFileSize.
Quindi la logica è descritta dal seguente codice (testato su Windows XP con i file/FAT/CDFS FAT32):
procedure FileSizeEx(const FileName: string; out Size, SizeOnDisk: UINT);
var
Drive: string;
FileHandle: THandle;
SectorsPerCluster,
BytesPerSector,
Dummy: DWORD;
ClusterSize: DWORD;
SizeHigh, SizeLow: DWORD;
begin
Assert(FileExists(FileName));
Drive := IncludeTrailingPathDelimiter(ExtractFileDrive(FileName));
if not GetDiskFreeSpace(PChar(Drive), SectorsPerCluster, BytesPerSector, Dummy, Dummy) then
RaiseLastOSError;
ClusterSize := SectorsPerCluster * BytesPerSector;
FileHandle := CreateFile(PChar(FileName), 0, FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil, OPEN_EXISTING, 0, 0);
if (FileHandle = INVALID_HANDLE_VALUE) then
RaiseLastOSError;
try
SizeLow := Windows.GetFileSize(FileHandle, @SizeHigh);
if (GetLastError <> NO_ERROR) and (SizeLow = INVALID_FILE_SIZE) then
RaiseLastOSError;
Size := UINT(SizeHigh shl 32 or SizeLow);
finally
if (FileHandle <> INVALID_HANDLE_VALUE) then
CloseHandle(FileHandle);
end;
SizeLow := GetCompressedFileSize(PChar(FileName), @SizeHigh);
if (GetLastError <> NO_ERROR) and (SizeLow = INVALID_FILE_SIZE) then
RaiseLastOSError;
SizeOnDisk := UINT(SizeHigh shl 32 or SizeLow);
if (SizeOnDisk mod ClusterSize) > 0 then
SizeOnDisk := SizeOnDisk + ClusterSize - (SizeOnDisk mod ClusterSize);
end;
Abbiamo potrebbe controllare la GetVolumeInformation
per la compressione/sparse supporto, e quindi GetFileAttributes
da provare per FILE_ATTRIBUTE_COMPRESSED
o FILE_ATTRIBUTE_SPARSE_FILE
, MA dal momento che il GetCompressedFileSize
lo fa internamente per noi (chiamando il numero NtQueryInformationFile
), non vedo alcun punto in questi test .
- 1. Come si ottiene il file su disco e non solo le dimensioni del file in Java?
- 2. Come ottenere informazioni sul buffer/file corrente in emacs?
- 3. Dimensioni DLL in memoria e dimensioni sul disco rigido
- 4. Java file di grandi dimensioni su disco IO Prestazioni
- 5. Chrome: Come salvare un file su disco
- 6. Dimensione directory Java su disco?
- 7. SchemaSpyGUI: Impossibile interrogare le informazioni sulla versione di Graphviz
- 8. Esiste un modo per stampare in batch le dimensioni del file su disco?
- 9. Le informazioni sul firmatario non corrispondono
- 10. Come copiare l'oggetto InMemoryUploadedFile sul disco
- 11. Come visualizzare le informazioni del file PFX in modo visivo?
- 12. Implementazione di un file di registro di dimensioni fisse o di un buffer circolare sul disco
- 13. Archivia i file su disco o MongoDB
- 14. Come ottimizzare le dimensioni del file PDF?
- 15. Aprire un file diretto sul disco rigido da firefox (file: ///)
- 16. Scrittura di un'immagine mascherata su disco come file PNG
- 17. come TRIM un blocco sul disco SSD?
- 18. quando DataContractJsonSerializer include le informazioni sul tipo?
- 19. JQuery - Drag n Drop Files - Come ottenere informazioni sul file?
- 20. Salvare le immagini sul disco rigido SENZA richiesta?
- 21. Come aggiungere informazioni sul copyright a un file pennino?
- 22. Spring Boot Actuator/endpoint salute non mostra le informazioni sul database o sul file system
- 23. Come ottenere le informazioni sul certificato dell'applicazione con codice
- 24. Come salvare un file XML su disco con python?
- 25. Come faccio a leggere i file immagine direttamente da un file zip senza estrarlo sul disco?
- 26. Come arrivare informazioni sul dispositivo in Android
- 27. C# XML.load() file sul errori del disco causando
- 28. test su spazio su disco in linux
- 29. .ttf kerning in iOS: come leggere le informazioni sul kerning?
- 30. Come aggiornare le informazioni sul fuso orario per OpenJDK?
Puoi ampliare ciò che intendi quando dici che "GetCompressedFileSize" non è la funzione corretta? –
@DavidHeffernan, intendevo consigliare un esperto contro l'ingresso nella stessa fossa apparentemente ovvia dopo di me ... – OnTheFly
Sei sicuro che non funzioni. Forse non sei riuscito a combinare correttamente il DWORD basso e alto. –