[
https://issues.apache.org/jira/browse/IO-373?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13612282#comment-13612282
]
Mark edited comment on IO-373 at 3/24/13 11:06 PM:
---------------------------------------------------
Here is a variant that is able to let the user specify the maximum number of
characters used to display the digits part of the displayed string. The
rounding also makes a lot of sense to me.
{code}
public class FileUtils {
private static final int DEFAULT_MAXCHARS = 3;
private static final BigDecimal KILO_DIVISOR = new BigDecimal(1024L);
enum SizeSuffix {
B, KB, MB, GB, TB, PB, EB, ZB, YB;
}
/**
* Adopted and improved version of
* {@link
org.apache.commons.io.FileUtils#byteCountToDisplaySize(BigInteger)}.
*
* @see https://issues.apache.org/jira/browse/IO-226 - should the rounding
be changed?
* @param size
* @param maxChars maximum length of digit part, ie. '1.2'
* @return rounded byte size as {@link java.lang.String}
*/
public static String byteCountToDisplaySize(BigInteger size, int maxChars) {
String displaySize;
BigDecimal bdSize = new BigDecimal(size);
SizeSuffix selectedSuffix = SizeSuffix.B;
for (SizeSuffix sizeSuffix : SizeSuffix.values()) {
if (sizeSuffix.equals(SizeSuffix.B)) {
continue;
}
if (bdSize.setScale(0, RoundingMode.HALF_UP).toString().length() <=
maxChars) {
break;
}
selectedSuffix = sizeSuffix;
bdSize = bdSize.divide(KILO_DIVISOR);
}
displaySize = bdSize.setScale(0, RoundingMode.HALF_UP).toString();
if (displaySize.length() < maxChars - 1) {
displaySize = bdSize.setScale(
maxChars - 1 - displaySize.length(),
RoundingMode.HALF_UP).toString();
}
return displaySize + " " + selectedSuffix.toString();
}
public static String byteCountToDisplaySize(BigInteger size) {
return byteCountToDisplaySize(size, DEFAULT_MAXCHARS);
}
public static String byteCountToDisplaySize(long size, int maxChars) {
return byteCountToDisplaySize(BigInteger.valueOf(size), maxChars);
}
public static String byteCountToDisplaySize(long size) {
return byteCountToDisplaySize(BigInteger.valueOf(size),
DEFAULT_MAXCHARS);
}
}
{code}
{code}
public class FileUtilsTest {
/**
* Test of byteCountToDisplaySize method, of class FileUtils.
*/
@Test
public void testByteCountToDisplaySize() {
assertEquals("99 B", FileUtils.byteCountToDisplaySize(99L));
assertEquals("999 B", FileUtils.byteCountToDisplaySize(999L));
assertEquals("1.0 KB", FileUtils.byteCountToDisplaySize(1000L));
assertEquals("1.0 KB", FileUtils.byteCountToDisplaySize(1023L));
assertEquals("1.1 KB", FileUtils.byteCountToDisplaySize(1124L));
assertEquals("1.1 KB", FileUtils.byteCountToDisplaySize(1164L));
assertEquals("999 KB", FileUtils.byteCountToDisplaySize(1024L * 999L +
511L));
assertEquals("1.0 MB", FileUtils.byteCountToDisplaySize(1024L * 999L +
512L));
assertEquals("1.0 MB", FileUtils.byteCountToDisplaySize(1024L * 1024L -
1L));
assertEquals("1.0 GB", FileUtils.byteCountToDisplaySize(1024L * 1024L *
1024L - 1L));
assertEquals("1.0 TB", FileUtils.byteCountToDisplaySize(1024L * 1024L *
1024L * 1024L - 1L));
assertEquals("1.0 PB", FileUtils.byteCountToDisplaySize(1024L * 1024L *
1024L * 1024L * 1024L - 1L));
assertEquals("1.0 EB", FileUtils.byteCountToDisplaySize(
1024L * 1024L * 1024L * 1024L * 1024L * 1024L - 1L));
BigInteger bi = BigInteger.valueOf(1024L * 1024L * 1024L * 1024L *
1024L * 1024L);
bi = bi.multiply(BigInteger.valueOf(1024L));
assertEquals("1.0 ZB", FileUtils.byteCountToDisplaySize(bi));
bi = bi.multiply(BigInteger.valueOf(1024L));
assertEquals("1.0 YB", FileUtils.byteCountToDisplaySize(bi));
bi = bi.multiply(BigInteger.valueOf(1024L));
assertEquals("1024 YB", FileUtils.byteCountToDisplaySize(bi));
bi = bi.multiply(BigInteger.valueOf(1024L));
assertEquals("1048576 YB", FileUtils.byteCountToDisplaySize(bi));
assertEquals("0 KB", FileUtils.byteCountToDisplaySize(100L, 2));
assertEquals("1 KB", FileUtils.byteCountToDisplaySize(1000L, 2));
assertEquals("1 KB", FileUtils.byteCountToDisplaySize(1023L, 2));
assertEquals("20 KB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 2));
assertEquals("20 KB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 3));
assertEquals("19.5 KB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 4));
assertEquals("196 KB", FileUtils.byteCountToDisplaySize(195L * 1024L +
512L, 4));
assertEquals("0 MB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 1));
assertEquals("1 KB",
org.apache.commons.io.FileUtils.byteCountToDisplaySize(2047));
}
}
{code}
was (Author: rnfm7avr):
Here is a variant that is able to let the user specify the maximum number
of characters used to display the digits part of the displayed string. The
rounding also makes a lot of sense to me.
{code}
public class FileUtils {
private static final int DEFAULT_MAXCHARS = 3;
private static final BigDecimal KILO_DIVISOR = new BigDecimal(1024L);
enum SizeSuffix {
B, KB, MB, GB, TB, PB, EB;
}
/**
* Adopted and improved version of
* {@link
org.apache.commons.io.FileUtils#byteCountToDisplaySize(BigInteger)}.
*
* @see https://issues.apache.org/jira/browse/IO-226 - should the rounding
be changed?
* @param size
* @param maxChars maximum length of digit part, ie. '1.2'
* @return rounded byte size as {@link java.lang.String}
*/
public static String byteCountToDisplaySize(BigInteger size, int maxChars) {
String displaySize;
BigDecimal bdSize = new BigDecimal(size);
SizeSuffix selectedSuffix = SizeSuffix.B;
for (SizeSuffix sizeSuffix : SizeSuffix.values()) {
selectedSuffix = sizeSuffix;
if (bdSize.setScale(0, RoundingMode.HALF_UP).toString().length() <=
maxChars) {
break;
}
bdSize = bdSize.divide(KILO_DIVISOR);
}
displaySize = bdSize.setScale(0, RoundingMode.HALF_UP).toString();
if (displaySize.length() < maxChars - 1) {
displaySize = bdSize.setScale(
maxChars - 1 - displaySize.length(),
RoundingMode.HALF_UP).toString();
}
return displaySize + " " + selectedSuffix.toString();
}
public static String byteCountToDisplaySize(BigInteger size) {
return byteCountToDisplaySize(size, DEFAULT_MAXCHARS);
}
public static String byteCountToDisplaySize(long size, int maxChars) {
return byteCountToDisplaySize(BigInteger.valueOf(size), maxChars);
}
public static String byteCountToDisplaySize(long size) {
return byteCountToDisplaySize(BigInteger.valueOf(size),
DEFAULT_MAXCHARS);
}
}
{code}
{code}
// CHECKSTYLE IGNORE MagicNumber FOR NEXT 1000 LINES
public class FileUtilsTest {
/**
* Test of byteCountToDisplaySize method, of class FileUtils.
*/
@Test
public void testByteCountToDisplaySize() {
assertEquals("999 B", FileUtils.byteCountToDisplaySize(999L));
assertEquals("1.0 KB", FileUtils.byteCountToDisplaySize(1000L));
assertEquals("1.0 KB", FileUtils.byteCountToDisplaySize(1023L));
assertEquals("1.1 KB", FileUtils.byteCountToDisplaySize(1124L));
assertEquals("1.1 KB", FileUtils.byteCountToDisplaySize(1164L));
assertEquals("999 KB", FileUtils.byteCountToDisplaySize(1024L * 999L +
511L));
assertEquals("1.0 MB", FileUtils.byteCountToDisplaySize(1024L * 999L +
512L));
assertEquals("1.0 MB", FileUtils.byteCountToDisplaySize(1024L * 1024L -
1L));
assertEquals("1.0 GB", FileUtils.byteCountToDisplaySize(1024L * 1024L *
1024L - 1L));
assertEquals("1.0 TB", FileUtils.byteCountToDisplaySize(1024L * 1024L *
1024L * 1024L - 1L));
assertEquals("1.0 PB", FileUtils.byteCountToDisplaySize(1024L * 1024L *
1024L * 1024L * 1024L - 1L));
assertEquals("1.0 EB", FileUtils.byteCountToDisplaySize(
1024L * 1024L * 1024L * 1024L * 1024L * 1024L - 1L));
assertEquals("0 KB", FileUtils.byteCountToDisplaySize(100L, 2));
assertEquals("1 KB", FileUtils.byteCountToDisplaySize(1000L, 2));
assertEquals("1 KB", FileUtils.byteCountToDisplaySize(1023L, 2));
assertEquals("20 KB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 2));
assertEquals("20 KB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 3));
assertEquals("19.5 KB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 4));
assertEquals("196 KB", FileUtils.byteCountToDisplaySize(195L * 1024L +
512L, 4));
assertEquals("0 MB", FileUtils.byteCountToDisplaySize(19L * 1024L +
512L, 1));
}
}
{code}
> FileUtils.byteCountToDisplaySize improvement/rounding issues
> ------------------------------------------------------------
>
> Key: IO-373
> URL: https://issues.apache.org/jira/browse/IO-373
> Project: Commons IO
> Issue Type: Improvement
> Components: Utilities
> Affects Versions: 2.4
> Reporter: Mark
> Priority: Minor
>
> Issue IO-226 is not fixed but closed.
> ?
> Here is my solution that also support a user-defined precision in terms of a
> maximum length of the digits part.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira