목차
바이트 단위 변환
파일 크기 102400000바이트를 그대로 보여주면 한눈에 읽기 어렵다. 1024로 두 번 나누면 97.65625가 되므로 소수 둘째 자리까지 표시하면 97.66 MiB다. 여기서 단위를 MB라고 쓰면 1000을 기준으로 하는 십진 단위와 섞인다.
| 단위 | 기준 | 1 단위의 바이트 수 |
|---|---|---|
| KB | 십진 | 1,000 |
| MB | 십진 | 1,000,000 |
| KiB | 이진 | 1,024 |
| MiB | 이진 | 1,048,576 |
같은 1,048,576바이트를 십진 기준으로 나타내면 약 1.05 MB, 이진 기준으로 나타내면 정확히 1 MiB다. 파일 관리 도구마다 단위를 표기하는 방법이 다를 수 있으므로 숫자만 비교하지 말고 기준도 확인해야 한다.
1024를 기준으로 변환하기
다음 메서드는 0 이상인 바이트 수를 받아 가장 큰 적절한 이진 단위로 표시한다. 입력을 숫자 문자열로 받지 않고 long으로 받아 파싱과 단위 변환을 분리했다.
import java.util.Locale;
public class ByteFormatter {
private static final String[] UNITS = {
"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"
};
public static String formatBytes(long bytes) {
if (bytes < 0) {
throw new IllegalArgumentException("바이트 수는 0 이상이어야 합니다.");
}
if (bytes < 1024) {
return bytes + " B";
}
double value = bytes;
int unit = 0;
while (value >= 1024 && unit < UNITS.length - 1) {
value /= 1024;
unit++;
}
return String.format(Locale.ROOT, "%.2f %s", value, UNITS[unit]);
}
public static void main(String[] args) {
System.out.println(formatBytes(0));
System.out.println(formatBytes(1023));
System.out.println(formatBytes(1024));
System.out.println(formatBytes(102400000));
}
}
0 B
1023 B
1.00 KiB
97.66 MiB
원래 메모의 계산식은 1000^n과 1024^n을 한 단위 설명에 섞었고, Math.log(0)을 사용하면 0의 단위 인덱스를 계산할 수 없었다. 위 코드는 0과 1024 미만을 먼저 처리해 그 문제를 없앴다. 음수는 파일 크기로 해석할 수 없으므로 명시적으로 거부한다.
double로 바꾸는 순간 아주 큰 long의 정수 정밀도는 일부 사라질 수 있다. 이 함수는 사람에게 보여줄 근삿값을 만드는 용도다. 정확한 바이트 수가 필요한 용량 제한, 과금, 전송 프로토콜에는 원래 long 값을 그대로 사용한다.