Jump to content

File Size


 Share

Recommended Posts

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..

Link to comment
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
Link to comment
Share on other sites

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
Link to comment
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
Link to comment
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.

Link to comment
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
Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...