
# DataSize

`DataSize` is an amount of data, such as an upload limit or a cache size, stored as a whole number of bytes.

## Why use it

Configuration can say `10MB` instead of `10485760`, and code reads a typed value instead of guessing the unit. The default conversion service turns `10MB`, `512KB`, `100` (bytes) and plain `int`s (bytes) into a `DataSize`. Declare a `@Value` parameter or a `@ConfigurationProperties` field of this type and use the result.

Rules for the text form:

- A whole number with an optional unit: `B`, `KB`, `MB`, `GB` or `TB`, in any case.
- Units are powers of 1024: `1KB` is 1024 bytes.
- Fractions fail: `1.5MB` is not valid.
- A number without a unit is bytes. `@DataSizeUnit` (from `spring_boot_dart`) changes that unit for a `@ConfigurationProperties` field.

Use a plain `int` when the value is a count, not an amount of data.

## Example

```properties
# lib/resources/application.properties
shop.upload.max-size=10MB
```

```dart
import 'package:spring_core_dart/spring_core_dart.dart';

@Service()
class UploadGuard {
  UploadGuard(@Value(r'${shop.upload.max-size:5MB}') this.maxSize);

  final DataSize maxSize;

  // Rejects bodies larger than the configured size.
  bool accepts(List<int> body) => body.length <= maxSize.toBytes();
}
```

In code:

```dart
DataSize.parse('10MB').toBytes(); // 10485760
DataSize.parse('2', unit: DataUnit.kilobytes).toBytes(); // 2048
DataSize.ofMegabytes(5).compareTo(DataSize.ofGigabytes(1)); // negative: smaller
DataSize.ofKilobytes(1536).toMegabytes(); // 1 (rounded toward zero)
DataSize.ofBytes(1024).toString(); // '1024B'
```

`DataSize` implements `Comparable<DataSize>` and `==`. It has no `<` operator; compare with `compareTo`.

## Members

| Name | Type | Meaning |
|---|---|---|
| `DataSize.ofBytes(int)` | constructor | A size of exactly that many bytes. |
| `DataSize.ofKilobytes(int)`, `ofMegabytes`, `ofGigabytes`, `ofTerabytes` | constructor | A size in that unit. |
| `DataSize.of(int amount, DataUnit unit)` | constructor | A size in a unit chosen at run time. |
| `DataSize.parse(text, {unit})` | `DataSize` | Reads `10MB`, `512kb`, `100`. A number without a unit is in `unit` (bytes unless given). Throws `FormatException` otherwise. |
| `toBytes()` | `int` | The size in bytes. |
| `toKilobytes()`, `toMegabytes()`, `toGigabytes()`, `toTerabytes()` | `int` | The size in whole units, rounded toward zero. |
| `isNegative` | `bool` | Whether the size is below zero. |
| `toString()` | `String` | The bytes with a `B` suffix (`10485760B`); `parse` reads it back. |

`DataUnit` values: `bytes` (`B`), `kilobytes` (`KB`), `megabytes` (`MB`), `gigabytes` (`GB`), `terabytes` (`TB`). Each has a `suffix` and a `byteCount`.

## In Spring (Java)

```java
@ConfigurationProperties("shop.upload")
class UploadProperties {
  private DataSize maxSize = DataSize.ofMegabytes(5);
  // getter and setter
}

DataSize size = DataSize.parse("10MB");
long bytes = size.toBytes();
```

Differences that matter:

- The API is the same as `org.springframework.util.unit.DataSize`, with Dart naming (`isNegative` is a getter).
- The amount is a Dart `int`. On the web, integers above 2^53 lose precision.

## See also

- [ConversionService](conversion-service.md)
- [Durations](durations.md)
- [@Value](../config/value.md)
- [@ConfigurationProperties](../config/configuration-properties.md)
