FormatBytes()

Post your working scripts, libraries and tools
User avatar
SKAN
Posts: 820
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



Lots of (alter)native versions available in this topic. Please peruse.
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: 820
Joined: 29 Sep 2013, 16:58

FormatBytes()

16 May 2014, 22:27

Example fixed. Thanks to Hamlet!
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: 1599
Joined: 01 Oct 2013, 14:57

Re: FormatBytes()

17 May 2014, 00:25

Nice, thanks!
HotKeyIt
Posts: 2144
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: 7770
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada
Contact:

Re: FormatBytes()

17 May 2014, 10:49

cool ;)
User avatar
SKAN
Posts: 820
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
joedf
Posts: 7770
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada
Contact:

Re: FormatBytes()

17 May 2014, 15:05

User avatar
SKAN
Posts: 820
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: 2663
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
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] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
SKAN
Posts: 820
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: 7770
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
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"
}
User avatar
jNizM
Posts: 2663
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
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] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
User avatar
joedf
Posts: 7770
Joined: 29 Sep 2013, 17:08
Facebook: J0EDF
Google: +joedf
GitHub: joedf
Location: Canada
Contact:

Re: FormatBytes()

13 Jul 2016, 08:53

Noooooooo! Whyyyyyyyy :cry:
User avatar
nnnik
Posts: 4470
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: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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: 2663
Joined: 30 Sep 2013, 01:33
GitHub: jNizM
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] 1.1.32.00 x64 Unicode | [WIN] 10 Pro (Version 2004) x64 | [GitHub] Profile
Donations are appreciated if I could help you
lexikos
Posts: 7088
Joined: 30 Sep 2013, 04:07
GitHub: Lexikos

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”

Who is online

Users browsing this forum: SirSocks and 13 guests