Is there a way to output file size on disk in batch?

2.1k views Asked by At

Is there a way to get the size on disk of a file like in the properties window:

I have tried:

(inside a batch file)

echo %~z1

,

for %i in (TestFile.txt) do echo %~zi

,

dir

But they only return the size of the file(s).

Is there any way to get the "size on disk" like the one seen in the properties window?

3

There are 3 answers

15
rojo On BEST ANSWER

Interesting question. I'm not aware of the size on disk value being a property of any scriptable object. You could calculate it by getting filesize modulo bytes-per-cluster, subtracting that modulo from the file size, then adding the cluster size. (Edit: or use Aacini's more efficient calculation, which I'm still trying to understand.)

@echo off
setlocal

for %%I in (Testfile.txt) do (
    set "fs=%%~zI"
    for /f %%J in (
        'wmic volume where "driveletter='%%~dI'" get blocksize /value'
    ) do 2>nul set /a %%J
)

echo Size: %fs%

set /a ondisk = ((fs-1)/blocksize+1) * blocksize

echo Size on disk: %ondisk%

Many websites claim that fsutil fsinfo ntfsinfo DRIVE: is the best way to obtain the bytes per cluster. It seems that this method is fraught with peril, with different labels depending on locale and different number of lines for different versions of Windows. Additionally, as Marged says, fsutil requires elevation. This WMI method seems to work more universally, and without requiring admin rights.

Thanks JosefZ, Marged, and Aacini for all your input!

6
Marged On

This is not intended to be an answer, just the values @rojo asked for:

NTFS-Volumeseriennummer             0xacf01e6ef01e3ed0
NTFS-Version :                           3.1
LFS-Version    :                  2.0
Anzahl der Sektoren :               0x000000000ed737ff
Gesamtzahl Cluster :                0x0000000001dae6ff
Freie Cluster :                     0x00000000008c8d41
Insgesamt reserviert :              0x0000000000000f70
Bytes pro Sektor  :                 512
Bytes pro physischem Sektor :       512
Bytes pro Cluster :                 4096
Bytes pro Dateidatensatzsegment   : 1024
Cluster pro Dateidatensatzsegment : 0
Gültige MFT-Datenlänge :            0x000000001c1c0000
MFT-Start-LCN  :                    0x00000000000c0000
MFT2-Start-LCN :                    0x0000000000000002
MFT-Zonenstart :                    0x00000000018a8ee0
MFT-Zonenende   :                   0x00000000018b12e0
Ressourcen-Manager-Bezeichner:        A81246B1-33B0-11E4-A94B-AEB4ABF863CB

This is from a German Windows 8.1. I think if it is necessary to make the batch locale independent you can not take the grepping approach. Instead scripting the appropriate filesystem object by using scripting host will be one solution.

The WMIC command has this result ...

SOMENAME,4096,C:\

... plus the advantage that I don't need to run this command with administrative rights.

0
GabrielB On

Looking for an answer to the same question, I just found this :
http://www.ltr-data.se/opencode.html/
The sizeof tool does just that.

sizeof, freeware by Olof Lagerkvist. http://www.ltr-data.se e-mail: [email protected] More info, including distribution permissions and source code is available on the website.

This tool displays the total allocation size on disk for files and directories.

Command line syntax: sizeof [-xo] [-presentation] file1 [file2 ...]

-x Do not follow junctions or other reparse points. This makes sure that sizeof stays within the filesystem where it starts searching.

-o Include sizes of offline files.

-c Count and display number of files in each found directory, instead of count and display sizes of them.

The presentation determines in which format to display the sizes of files and directories. The argument can be any of the following:

-b Number of 512-byte blocks. -h Human readable format. -k Kilobytes. -m Megabytes. -g Gigabytes. -t Terabytes.

It's better than some other solutions proposed on this page as it provides the correct “size on disk” (which by the way should be renamed to “size on partition” or “size on storage device” as nowadays many storage devices are not “disks”) for compressed or sparse files. I precisely wanted to compare the effect of NTFS compression and “sparseness” for a bunch of large files which are partial downloads from a file sharing software; so I'm going to first use sizeof to get the actual allocated size of those files which are currently compressed, then I'm going to uncompress them, then convert them to “sparse”, then run sizeof again.

I've only found one utility which can convert a non-sparse file to sparse, and actually de-allocate its empty sectors : a command line tool called SparseTest, which was released more than 10 years ago, “for demo purposes only”, and seems to have vanished long ago, but is still available there :
https://web.archive.org/web/20151103231305if_/http://pages.infinit.net/moonligh/eMule/Releases/SparseTest.zip

SparseTest also displays the “size on disk” before applying the “sparse” attribute (but the output is more complex so it wouldn't be easy to use in a batch script if that information is needed for a further purpose). It calculates a checksum before and after to ensure that the file's integrity was preserved in the process (I'd still recommand to make a backup first, and verifying that all files are strictly identical afterwards with another tool, like WinMerge or MD5Checker). Contrary to files with the “C” attribute, which appear in blue color, nothing distinguishes “sparse” files from regular files, except the “P” in the Attributes column (and it does not even appear in the Properties).

The native Windows tool fsutil can set the sparse attribute, but it does not actually compress the file, its “size on disk” remains unchanged even if it contains a lot of empty sectors; only if the file size is later increased with empty sectors will they be added in a “sparse” manner, i.e. stored as metadata and not actually allocated.