Summary#
A file's size is stored as a number of bytes and read by a person as words. Text.ByteSize converts one to the other:
string SizeLabel(int bytes) {
return Text.ByteSize(bytes); // 2831155 → "2.7 MB"
}Signature#
string Text.ByteSize(<int> bytes)Description#
Units are binary (1024 per step) with the conventional labels — B, KB, MB, GB, TB, PB — which is what
du -h, docker and node print, and what a developer reading a file size expects.
Whole bytes read as an integer; everything above carries one decimal:
| bytes | reads as |
|---|---|
0 | 0 B |
999 | 999 B |
1024 | 1.0 KB |
1536 | 1.5 KB |
2831155 | 2.7 MB |
A negative count is clamped to 0 B — a negative size is not a thing, and -5 B would only ever be a bug showing
through. The answer is identical on the server and in the browser, so the same expression is safe wherever it runs.
Why a function, not a column setting#
A size is not only ever shown in a grid. The same string belongs in a detail line, a tooltip, a confirmation message — so formatting lives in a function you call, not in a format flag on some control's contract. A grid renders one with an ordinary cell template:
Grid(rows: files, columns: [ new GridColumn { Key = "Size", Label = "Size", Align = "right" } ]) { f =>
slot Size { f => Text(Text.ByteSize(f.Size)); }
}The alternative — a Format = "bytes" marker on the column — would have to be re-invented on every surface that ever
shows a size, and the next format after it (durations, percentages, compact counts) would each need their own marker.
A function composes; a marker is a catalogue.
See also#
- Convert — the general value → string conversions
- control — foreign UI controls (charts, grids, maps) — cell templates, where a grid calls this