Hi spring dev community,
I found something quite confusing when using org.springframework.util.unit.DataSize
, or org.springframework.util.unit.DataUnit
.
Spring framework version is 6.2.8
Enhancements requests
When using DataSize class, if we run this spring test :
```java
package com.example.demo;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.util.unit.DataSize;
@ExtendWith(MockitoExtension.class) class DumbTest {
@Test
void test() {
System.out.println(DataSize.ofMegabytes(10).toBytes());
}
}
we have this console print :
```bash
10485760
This result is quite confusing since 10 megabytes (MB) should represent 10 million bytes , which would be 10 000 000 bytes.
Actually it seems `DataSize.ofMegabytes(10) is actually representing 10 mebibytes (10MiB) that represent 10 485 760 bytes.
So what is confusing is when we use the toBytes()
method because converting megabytes (MB) to bytes (B) seems not to be accurate.
Could we improve the class so we could have methods concernnin bytes and bibytes ? Same for DataUnit that would be based on DataSize, we would have something like DataUnit.MEGABYTES and DataUnit.MEBIBYTES.
Same things apply to other power of ten (kilo, mega, giga, tera...).
The way we could solve this is just by modifing DataSize code like so :
// --------------------- Existing code example for toKilobytes ------------------------
public final class DataSize implements Comparable<DataSize>, Serializable {
private static final long BYTES_PER_KB = 1024L;
private static final long BYTES_PER_MB = 1048576L;
private static final long BYTES_PER_GB = 1073741824L;
private static final long BYTES_PER_TB = 1099511627776L;
// Other method in other powers of ten
public static DataSize ofKilobytes(long kilobytes) {
return new DataSize(Math.multiplyExact(kilobytes, BYTES_PER_KB));
}
// Other method in other powers of ten
}
// ----------------------- Changed code --------------------------
public final class DataSize implements Comparable<DataSize>, Serializable {
private static final long BYTES_PER_KB = 1000L;
private static final long BYTES_PER_MB = 1000000L;
private static final long BYTES_PER_GB = 1000000000L;
private static final long BYTES_PER_TB = 1000000000000L;
private static final long BYTES_PER_KIB = 1024L;
private static final long BYTES_PER_MIB = 1048576L;
private static final long BYTES_PER_GIB = 1073741824L;
private static final long BYTES_PER_TIB = 1099511627776L;
// Other method in other powers of ten
public static DataSize ofKilobytes(long kilobytes) {
return new DataSize(Math.multiplyExact(kilobytes, BYTES_PER_KB));
}
public static DataSize ofKibibytes(long kibibytes) {
return new DataSize(Math.multiplyExact(kilobytes, BYTES_PER_KIB));
}
// Other method in other powers of ten
// parsers to modify
}
Tank you :)
Comment From: sbrannen
Related Issues
-
23682
-
23697
Comment From: elienFR
thanks for the answer
Comment From: sbrannen
thanks for the answer
You're welcome.