FormatBytes()

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

FormatBytes()

16 May 2014, 20:22

Usage: FormatBytes( 1048576 ) ; returns 1.00 MB

Code: Select all

FormatBytes(N) { ; By SKAN on CT5H/D351 @ tiny.cc/formatbytes
Return DllCall("Shlwapi\StrFormatByteSize64A", "Int64",N, "Str",Format("{:16}",N), "Int",16, "AStr") 
}

; Usage example :
DskSts := "", FBA := 0, TNB := 0
DriveGet, List, List
Loop, Parse, List
 If DllCall( "GetDiskFreeSpaceEx", "Str",A_LoopField ":\", "Int64P",FBA, "Int64P",TNB, "Ptr",0 )
     DskSts .= A_LoopField ":\`t" FormatBytes( FBA ) "`t( " FormatBytes( TNB ) " )`n"
Msgbox, 64, Drive Free Space, % DskSts


 
V2 specific version:

Code: Select all

#Requires AutoHotkey v2.0

MsgBox FormatBytes(0x7FFFFFFFFFFFFFFF) ; 7.99 EB

FormatBytes(N) ; By SKAN for ah2 on CT5H/D68S @ autohotkey.com/r?t=3567
{
    Return DllCall("Shlwapi\StrFormatByteSizeW", "int64",N, "str",Format("{:16}",""), "int",16, "str")
}
 
Lots of (alter)native versions available in this topic. Please peruse.
My Scripts and Functions: V1  V2
Guest10
Posts: 578
Joined: 01 Oct 2013, 02:50

Re: FormatBytes()

16 May 2014, 21:01

thanks, it hit the spot! :lol:
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

FormatBytes()

16 May 2014, 22:27

Example fixed. Thanks to Hamlet!
My Scripts and Functions: V1  V2
Hamlet
Posts: 32
Joined: 02 Oct 2013, 09:55
Location: Seoul, Korea

Re: FormatBytes()

16 May 2014, 23:25

You saw that.
That was not the point here, that's why I deleted it.

Anyways.
Thanks.
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: FormatBytes()

17 May 2014, 00:25

Nice, thanks!
HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: FormatBytes()

17 May 2014, 04:51

Here is one written in AHK.
Advantages: no dependencies, faster, keeps dot '.' as comma separator instead using locale (e.g. ',' in german).
AutoHotkey v1:

Code: Select all

FormatByteSize(Bytes){
  static size:="bytes,KB,MB,GB,TB,PB,EB,ZB,YB"
  Loop,Parse,size,`,
    If (bytes>999)
      bytes:=bytes/1024
    else {
      bytes:=Trim(SubStr(bytes,1,4),".") " " A_LoopField
      break
    }
  return bytes
}
AutoHotkey v2:

Code: Select all

FormatByteSize(Bytes){
  static size:="bytes,KB,MB,GB,TB,PB,EB,ZB,YB"
  LoopParse,%size%,`,
    If bytes>999,bytes/=1024
    else if bytes:=RTrim(SubStr(bytes,1,4),".") " " A_LoopField,break
  return bytes
}
EDIT:
Changed bytes>999 to match StrFormatByteSize64, thanks SKAN ;)
User avatar
joedf
Posts: 8958
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: FormatBytes()

17 May 2014, 10:49

cool ;)
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

FormatBytesEX()

17 May 2014, 13:08

HotKeyIt wrote:Here is one written in AHK.
Advantages: no dependencies, faster, keeps dot '.' as comma separator instead using locale (e.g. ',' in german).
Thanks for sharing, HotKeyIt :)
One may simply use StringReplace to rectify the locale problem.

I tried your code and like to share my observations.
1) If (bytes>1024) should be If (bytes>1023).
2) Maximum format-able bytes is 0xFFFFFFFFFFFFFFFF ( 7.99 EB ). The extra ZB,YB seems redundant ( does not hurt, though )
3) FormatByteSize( 0xFFFFFFFF ) should return 3.99 GB but rounds the result to 4.00 GB owing to the default FloatFormat of 0.6
4) FormatByteSize( 1024*1023 ) returns 1023 KB, whereas StrFormatByteSize64A() returns a more readable 0.99 MB.

The advantages of WinAPI Shlwapi\StrFormatByteSize64A():
1) High Precision. 0xFFFFFFFFFFFFFFFF will be correctly formatted as 7.99 EB, but with AHK's highest precision of 15 digits, incorrect rounding occurs above 4.00 PB.
2) It formats the result to fit a common width by losing decimal places. This is aesthetically good on a GUI.

Example:

390 MB
93.2 MB
74.3 KB
41.8 KB
67.6 KB
7.61 KB

Image

Here is my attempted native code: FormatBytesEx()
Note: Precision is lost somewhere above 4.00 PB

Algorithm:
1) When bytes < 1000, return ( bytes . " bytes" ).
2) Return string will not contain more than 3 digits ( irrespective of a period ).
3) Return string may have 1 decimal period, only when required.

Code: Select all

FormatBytesEx( Bytes ) { ; By SKAN,    http://ahkscript.org/boards/viewtopic.php?p=18352#p18352
Static B1 := "KB", B2 := "MB", B3 := "GB", B4 := "TB", B5 := "PB", B6 := "EB"
  IfLess, Bytes, 1000, Return Bytes + 0 " bytes"
  AFF := A_FormatFloat
  SetFormat, FloatFast, 0.15

  While ( FL>3 or FL="" ) {
    FBytes := Bytes / ( 1024 ** ( IX := A_Index ) )
    StringSplit, F, FBytes, .
    FL := StrLen( F1 ) 
  }

  SetFormat, FloatFast, %AFF%
Return F1 ( FL<3 ? "." SubStr( F2, 1, 3-FL ) : "" ) " " B%IX% 
}
Simple test FormatBytes() vs FormatBytesEx() vs FormatByteSize().

Code: Select all

A := "0xF"
Loop 15
 R .= FormatBytes( A .= "F" ) "`t" FormatBytesEx( A  ) "`t" FormatByteSize( A + 0 ) "`n"
MsgBox % R
Result:
Image
Guest10
Posts: 578
Joined: 01 Oct 2013, 02:50

Re: FormatBytes()

17 May 2014, 13:16

thanks, i needed my ahk script fix this morning! :lol: :ugeek:
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: FormatBytes()

18 May 2014, 03:49

HotKeyIt wrote: EDIT:
Changed bytes>999 to match StrFormatByteSize64, thanks SKAN ;)
StrFormatByteSize64() formats only > 1023 bytes, but > 999 is better. Thanks.. I also changed. :)
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: FormatBytes()

18 May 2014, 04:05

n1 script SKAN =)
Ive heard you share your netmeter script =)

because your old script dont work well (see htopmini - nettraffic)
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: FormatBytes()

18 May 2014, 19:39

jNizM wrote:n1 script SKAN =)
Thanks. :)
Ive heard you share your netmeter script =)
I haven't shared it yet as I need to test it in x64.
your old script dont work well
That doesn't help me to understand the problem. Please bump your topic ( or ask for help ) with a detailed query.
User avatar
joedf
Posts: 8958
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: FormatBytes()

18 May 2014, 22:07

How about something like so? :?:

Code: Select all

formatbytes(bytes) {
	static unit_prefixes := ["","K","M","G","T","P","E","Z","Y"]
	upf_i := floor(log(bytes)/log(1024))
	upf := unit_prefixes[upf_i+1]
	sz_f := bytes/(1024**upf_i)
	return sz_f . " " . upf . "B"
}

MsgBox % formatbytes(1024**5)
EDIT/UPDATE : I edited mine jumbled up with SKAN's. Now it's way faster.

Code: Select all

FormatBytes( Bytes ) {
	Static B1 := "K", B2 := "M", B3 := "G", B4 := "T", B5 := "P", B6 := "E"
	upf_i := floor(log(bytes)/log(1024))
	sz_f := bytes/(1024**upf_i)
	return sz_f " " upf " " B%upf_i% "B"
}
QPX results
Spoiler
EDIT2 Here is another variant which changes 1024 MB to 1.00 GB, Speed is affected a tiny bit.

Code: Select all

FormatBytes( Bytes ) {
	Static B1 := "K", B2 := "M", B3 := "G", B4 := "T", B5 := "P", B6 := "E"
	IfLess, Bytes, 1000, Return Bytes + 0 " bytes"
	upf_i := floor(log(Bytes)/log(1024)), sz_f := Bytes/(1024**upf_i)
	loop
		IfLess, sz_f, 1000, break
		else sz_f := sz_f/1024, upf_i+=1
	return Round(sz_f,2) " " B%upf_i% "B"
}
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: FormatBytes()

13 Jul 2016, 08:36

Just a short info about StrFormatByteSize64
StrFormatByteSize64 function wrote:Remarks
In Windows 10, size is reported in base 10 rather than base 2. For example, 1 KB is 1000 bytes rather than 1024.
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
User avatar
joedf
Posts: 8958
Joined: 29 Sep 2013, 17:08
Location: Canada
Contact:

Re: FormatBytes()

13 Jul 2016, 08:53

Noooooooo! Whyyyyyyyy :cry:
Image Image Image Image Image
Windows 10 x64 Professional, Intel i5-8500, NVIDIA GTX 1060 6GB, 2x16GB Kingston FURY Beast - DDR4 3200 MHz | [About Me] | [About the AHK Foundation] | [Courses on AutoHotkey]
[ASPDM - StdLib Distribution] | [Qonsole - Quake-like console emulator] | [LibCon - Autohotkey Console Library]
User avatar
nnnik
Posts: 4500
Joined: 30 Sep 2013, 01:01
Location: Germany

Re: FormatBytes()

13 Jul 2016, 16:31

Wow
This will break so much code xD.
Recommends AHK Studio
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: FormatBytes()

14 Jul 2016, 03:08

No, the documentation is clearly wrong. On Windows 10.0.10586, SKAN's example code and Explorer itself both show 1GB as 1024*1024*1024 bytes.
User avatar
jNizM
Posts: 3183
Joined: 30 Sep 2013, 01:33
Contact:

Re: FormatBytes()

14 Jul 2016, 04:23

Maybe with the "Anniversary Update" in August?
* update my vm to the latest insider build and will test it
[AHK] v2.0.5 | [WIN] 11 Pro (Version 22H2) | [GitHub] Profile
lexikos
Posts: 9592
Joined: 30 Sep 2013, 04:07
Contact:

Re: FormatBytes()

14 Jul 2016, 05:10

I suspect that it was either an early change that was withdrawn before the retail release, or an early change that was planned but never actually happened. This is present in documentation from before the release of Windows 10 proper:
In Windows 10 Insider Preview, size is reported in base 10 rather than base 2. For example, 1 KB is 1000 bytes rather than 1024.
Source: StrFormatByteSize64 function (Windows)
The table shown below that includes examples of how it would work if the change actually happened. Earlier versions of the documentation had correct examples. Seems like whoever updated the documentation (removing "Insider Preview") erroneously assumed that the earlier comment (still) applied.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 121 guests