
# DataSize

`DataSize` は、アップロード上限やキャッシュサイズのようなデータ量を、バイト数の整数として保持します。

## 使う理由

設定に `10485760` ではなく `10MB` と書けて、コードは単位を推測せずに型付きの値を読めます。デフォルトの変換サービスは `10MB`、`512KB`、`100`(バイト)、および単なる `int`(バイト)を `DataSize` に変換します。この型の `@Value` パラメーターや `@ConfigurationProperties` のフィールドを宣言して、結果を使ってください。

テキスト形式のルール:

- 整数と、省略可能な単位 `B`、`KB`、`MB`、`GB`、`TB`(大文字小文字は問わない)。
- 単位は 1024 の累乗です。`1KB` は 1024 バイトです。
- 小数は失敗します。`1.5MB` は無効です。
- 単位のない数値はバイトです。`@DataSizeUnit`(`spring_boot_dart` のアノテーション)を使うと、`@ConfigurationProperties` のフィールドでこの単位を変えられます。

値がデータ量ではなく個数なら、単なる `int` を使ってください。

## 例

```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;

  // 設定されたサイズより大きい本文を拒否する。
  bool accepts(List<int> body) => body.length <= maxSize.toBytes();
}
```

コードでの使い方:

```dart
DataSize.parse('10MB').toBytes(); // 10485760
DataSize.parse('2', unit: DataUnit.kilobytes).toBytes(); // 2048
DataSize.ofMegabytes(5).compareTo(DataSize.ofGigabytes(1)); // 負の値: 小さい
DataSize.ofKilobytes(1536).toMegabytes(); // 1 (0 方向に切り捨て)
DataSize.ofBytes(1024).toString(); // '1024B'
```

`DataSize` は `Comparable<DataSize>` と `==` を実装しています。`<` 演算子はないので、`compareTo` で比較してください。

## メンバー

| 名前 | 型 | 意味 |
|---|---|---|
| `DataSize.ofBytes(int)` | コンストラクター | ちょうどそのバイト数のサイズ。 |
| `DataSize.ofKilobytes(int)`、`ofMegabytes`、`ofGigabytes`、`ofTerabytes` | コンストラクター | その単位でのサイズ。 |
| `DataSize.of(int amount, DataUnit unit)` | コンストラクター | 実行時に選んだ単位でのサイズ。 |
| `DataSize.parse(text, {unit})` | `DataSize` | `10MB`、`512kb`、`100` を読む。単位のない数値は `unit`(指定がなければバイト)。それ以外は `FormatException`。 |
| `toBytes()` | `int` | バイト数。 |
| `toKilobytes()`、`toMegabytes()`、`toGigabytes()`、`toTerabytes()` | `int` | その単位での整数値。0 方向に切り捨て。 |
| `isNegative` | `bool` | 0 未満かどうか。 |
| `toString()` | `String` | `B` 付きのバイト数(`10485760B`)。`parse` で読み戻せる。 |

`DataUnit` の値: `bytes`(`B`)、`kilobytes`(`KB`)、`megabytes`(`MB`)、`gigabytes`(`GB`)、`terabytes`(`TB`)。それぞれ `suffix` と `byteCount` を持ちます。

## 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();
```

重要な違い:

- API は `org.springframework.util.unit.DataSize` と同じで、名前は Dart の流儀に合わせています(`isNegative` はゲッター)。
- 量は Dart の `int` です。Web では 2^53 を超える整数は精度が落ちます。

## 関連項目

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