Sign in to follow this  
Followers 0
anixon

File Size

7 posts in this topic

FileGetSize(Test.txt) produces a size of 383 byte which is the value in the files properties however the Size on disc is 4096 bytes so my question is how do I either read or calculate the size on disc for any given file? Ant..

Share this post


Link to post
Share on other sites



A Script made by the absolutely great AutoIt-Scriptomatic tool: 

"Bytes per Sector " is what you need...

; Generated by AutoIt Scriptomatic

$wbemFlagReturnImmediately = 0x10
$wbemFlagForwardOnly = 0x20
$colItems = ""
$strComputer = "localhost"

$Output=""
$Output = $Output & "Computer: " & $strComputer  & @CRLF
$Output = $Output & "==========================================" & @CRLF
$objWMIService = ObjGet("winmgmts:\\" & $strComputer & "\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_DiskDrive", "WQL", _
                                          $wbemFlagReturnImmediately + $wbemFlagForwardOnly)

If IsObj($colItems) then
   For $objItem In $colItems
      $Output = $Output & "Availability: " & $objItem.Availability & @CRLF
      $Output = $Output & "BytesPerSector: " & $objItem.BytesPerSector & @CRLF
      $strCapabilities = $objItem.Capabilities(0)
      $Output = $Output & "Capabilities: " & $strCapabilities & @CRLF
      $strCapabilityDescriptions = $objItem.CapabilityDescriptions(0)
      $Output = $Output & "CapabilityDescriptions: " & $strCapabilityDescriptions & @CRLF
      $Output = $Output & "Caption: " & $objItem.Caption & @CRLF
      $Output = $Output & "CompressionMethod: " & $objItem.CompressionMethod & @CRLF
      $Output = $Output & "ConfigManagerErrorCode: " & $objItem.ConfigManagerErrorCode & @CRLF
      $Output = $Output & "ConfigManagerUserConfig: " & $objItem.ConfigManagerUserConfig & @CRLF
      $Output = $Output & "CreationClassName: " & $objItem.CreationClassName & @CRLF
      $Output = $Output & "DefaultBlockSize: " & $objItem.DefaultBlockSize & @CRLF
      $Output = $Output & "Description: " & $objItem.Description & @CRLF
      $Output = $Output & "DeviceID: " & $objItem.DeviceID & @CRLF
      $Output = $Output & "ErrorCleared: " & $objItem.ErrorCleared & @CRLF
      $Output = $Output & "ErrorDescription: " & $objItem.ErrorDescription & @CRLF
      $Output = $Output & "ErrorMethodology: " & $objItem.ErrorMethodology & @CRLF
      $Output = $Output & "Index: " & $objItem.Index & @CRLF
      $Output = $Output & "InstallDate: " & WMIDateStringToDate($objItem.InstallDate) & @CRLF
      $Output = $Output & "InterfaceType: " & $objItem.InterfaceType & @CRLF
      $Output = $Output & "LastErrorCode: " & $objItem.LastErrorCode & @CRLF
      $Output = $Output & "Manufacturer: " & $objItem.Manufacturer & @CRLF
      $Output = $Output & "MaxBlockSize: " & $objItem.MaxBlockSize & @CRLF
      $Output = $Output & "MaxMediaSize: " & $objItem.MaxMediaSize & @CRLF
      $Output = $Output & "MediaLoaded: " & $objItem.MediaLoaded & @CRLF
      $Output = $Output & "MediaType: " & $objItem.MediaType & @CRLF
      $Output = $Output & "MinBlockSize: " & $objItem.MinBlockSize & @CRLF
      $Output = $Output & "Model: " & $objItem.Model & @CRLF
      $Output = $Output & "Name: " & $objItem.Name & @CRLF
      $Output = $Output & "NeedsCleaning: " & $objItem.NeedsCleaning & @CRLF
      $Output = $Output & "NumberOfMediaSupported: " & $objItem.NumberOfMediaSupported & @CRLF
      $Output = $Output & "Partitions: " & $objItem.Partitions & @CRLF
      $Output = $Output & "PNPDeviceID: " & $objItem.PNPDeviceID & @CRLF
      $strPowerManagementCapabilities = $objItem.PowerManagementCapabilities(0)
      $Output = $Output & "PowerManagementCapabilities: " & $strPowerManagementCapabilities & @CRLF
      $Output = $Output & "PowerManagementSupported: " & $objItem.PowerManagementSupported & @CRLF
      $Output = $Output & "SCSIBus: " & $objItem.SCSIBus & @CRLF
      $Output = $Output & "SCSILogicalUnit: " & $objItem.SCSILogicalUnit & @CRLF
      $Output = $Output & "SCSIPort: " & $objItem.SCSIPort & @CRLF
      $Output = $Output & "SCSITargetId: " & $objItem.SCSITargetId & @CRLF
      $Output = $Output & "SectorsPerTrack: " & $objItem.SectorsPerTrack & @CRLF
      $Output = $Output & "Signature: " & $objItem.Signature & @CRLF
      $Output = $Output & "Size: " & $objItem.Size & @CRLF
      $Output = $Output & "Status: " & $objItem.Status & @CRLF
      $Output = $Output & "StatusInfo: " & $objItem.StatusInfo & @CRLF
      $Output = $Output & "SystemCreationClassName: " & $objItem.SystemCreationClassName & @CRLF
      $Output = $Output & "SystemName: " & $objItem.SystemName & @CRLF
      $Output = $Output & "TotalCylinders: " & $objItem.TotalCylinders & @CRLF
      $Output = $Output & "TotalHeads: " & $objItem.TotalHeads & @CRLF
      $Output = $Output & "TotalSectors: " & $objItem.TotalSectors & @CRLF
      $Output = $Output & "TotalTracks: " & $objItem.TotalTracks & @CRLF
      $Output = $Output & "TracksPerCylinder: " & $objItem.TracksPerCylinder & @CRLF
      if Msgbox(1,"WMI Output",$Output) = 2 then ExitLoop
      $Output=""
   Next
Else
   Msgbox(0,"WMI Output","No WMI Objects Found for class: " & "Win32_DiskDrive" )
Endif


Func WMIDateStringToDate($dtmDate)

    Return (StringMid($dtmDate, 5, 2) & "/" & _
    StringMid($dtmDate, 7, 2) & "/" & StringLeft($dtmDate, 4) _
    & " " & StringMid($dtmDate, 9, 2) & ":" & StringMid($dtmDate, 11, 2) & ":" & StringMid($dtmDate,13, 2))
EndFunc

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Delving into 'Undocumented' territory, here's a simple way to get it:

#include <WinAPI.au3>

; Author: Ascend4nt

Func _FileGetSizeOnDisk($sFilename)
    Local $aRet,$hFile,$iErr
    $hFile=_WinAPI_CreateFile($sFilename,2,2,6)
    If $hFile=0 Then Return SetError(-1,@error,-1)
    Local $stStandInfo=DllStructCreate("uint64;uint64;ulong;boolean;boolean"),$stIOStatusBlock=DllStructCreate("ulong_ptr;ulong_ptr")
    $aRet=DllCall("ntdll.dll","long","NtQueryInformationFile","handle",$hFile,"ptr",DllStructGetPtr($stIOStatusBlock),"ptr",DllStructGetPtr($stStandInfo),"ulong",DllStructGetSize($stStandInfo),"ulong",5)
    $iErr=@error
    _WinAPI_CloseHandle($hFile)
    If $iErr Then Return SetError(2,$iErr,-1)
    If $aRet[0] Then Return SetError(6,$aRet[0],-1)
    Return DllStructGetData($stStandInfo,1)
EndFunc
$sFile=@SystemDir&"\user32.dll"
ConsoleWrite("FileSize:"&FileGetSize($sFile)&", Allocation size:"&_FileGetSizeOnDisk($sFile)&", @error="&@error&", @extended="&@extended&@CRLF)

*edit: added NTSTATUS check

Edited by Ascend4nt

Share this post


Link to post
Share on other sites

What are the reasons to use an undocumented function?

$FileSizeOnDisk = Ceiling($FileSize / $ClusterSize) * $ClusterSize

Func _FileGetSizeOnDisk($sFile)

    Local $aRet, $tPath, $Bytes

    $tPath = DllStructCreate('wchar[260]')
    $aRet = DllCall('shlwapi.dll', 'int', 'PathSearchAndQualifyW', 'wstr', StringStripWS($sFile, 7), 'ptr', DllStructGetPtr($tPath), 'int', 260)
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    $sFile = DllStructGetData($tPath, 1)
    $aRet = DllCall('kernel32.dll', 'int', 'GetDiskFreeSpaceW', 'wstr', StringLeft($sFile, 2), 'dword*', 0, 'dword*', 0, 'dword*', 0, 'dword*', 0)
    If (@error) Or (Not $aRet[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    $Bytes = $aRet[2] * $aRet[3]
    Return Ceiling(FileGetSize($sFile) / $Bytes) * $Bytes
EndFunc   ;==>_FileGetSizeOnDisk

Share this post


Link to post
Share on other sites

Actually most every 'undocumented' API function that I use are documented in some form or another on MSDN. The above function NtQueryInformationFile can be found listed under ZwQueryInformationFile. The difference is 'Nt' is supposed to be called from user mode.

Share this post


Link to post
Share on other sites

I would like to thank everyone for their contribution which is very much appreciated Ant..

Share this post


Link to post
Share on other sites

What are the reasons to use an undocumented function?

$FileSizeOnDisk = Ceiling($FileSize / $ClusterSize) * $ClusterSize

Func _FileGetSizeOnDisk($sFile)

    Local $aRet, $tPath, $Bytes

    $tPath = DllStructCreate('wchar[260]')
    $aRet = DllCall('shlwapi.dll', 'int', 'PathSearchAndQualifyW', 'wstr', StringStripWS($sFile, 7), 'ptr', DllStructGetPtr($tPath), 'int', 260)
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    $sFile = DllStructGetData($tPath, 1)
    $aRet = DllCall('kernel32.dll', 'int', 'GetDiskFreeSpaceW', 'wstr', StringLeft($sFile, 2), 'dword*', 0, 'dword*', 0, 'dword*', 0, 'dword*', 0)
    If (@error) Or (Not $aRet[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    $Bytes = $aRet[2] * $aRet[3]
    Return Ceiling(FileGetSize($sFile) / $Bytes) * $Bytes
EndFunc   ;==>_FileGetSizeOnDisk

I took the liberty of modifying your code to calculate KB or MB as the case may be hope you don't mind.. Ant

;//Calculate Distribution File Size
Func _FileGetSizeOnDisk($sFile)
    Local $aRet, $tPath, $Bytes
    $tPath = DllStructCreate('wchar[260]')
    $aRet = DllCall('shlwapi.dll', 'int', 'PathSearchAndQualifyW', 'wstr', StringStripWS($sFile, 7), 'ptr', DllStructGetPtr($tPath), 'int', 260)
    If @error Then
        Return SetError(1, 0, 0)
    EndIf
    $sFile = DllStructGetData($tPath, 1)
    $aRet = DllCall('kernel32.dll', 'int', 'GetDiskFreeSpaceW', 'wstr', StringLeft($sFile, 2), 'dword*', 0, 'dword*', 0, 'dword*', 0, 'dword*', 0)
    If (@error) Or (Not $aRet[0]) Then
        Return SetError(1, 0, 0)
    EndIf
    $Bytes = $aRet[2] * $aRet[3]
    $sDistributionCal = Ceiling(FileGetSize($sFile) / $Bytes) * $Bytes)
 ;//Calculate the KB Value
 $sDistributionSize = StringFormat("%0.2f", $sDistributionCal / 1024) & " KB"
 ;//Calculate the MB Value if Bytes >= 1048576
 If $sDistributionCal >= 1048576 Then $sDistributionSize = StringFormat("%0.2f", $sDistributionCal / 1048576) & " MB"
EndFunc   ;==>_FileGetSizeOnDisk

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0