# Text.ByteSize

> Formats a byte count as the words a person reads — "0 B", "1.5 KB", "2.7 MB". Binary units (1024) with the conventional KB/MB/GB labels. An ordinary function, so the same call formats a size in a grid cell, a detail line or a tooltip.

<!-- id: function-text-bytesize · area: function · stability: stable · html: https://osysharp.com/reference/function/text-bytesize/ -->

## Summary        {#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:

```osy title="a size a person can read" test app=text-bytesize
string SizeLabel(int bytes) {
  return Text.ByteSize(bytes);     // 2831155 → "2.7 MB"
}
```

## Signature      {#signature}
```osy syntax
string Text.ByteSize(<int> bytes)
```

## Description    {#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   {#why-a-function}
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](https://osysharp.com/reference/ui/controls/):

```osy syntax
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       {#see-also}
- [Convert](https://osysharp.com/reference/function/convert/) — the general value → string conversions
- [control — foreign UI controls (charts, grids, maps)](https://osysharp.com/reference/ui/controls/) — cell templates, where a grid calls this
