Java tutorial
/* * @(#)Bytes.java 2.0 Sept 30, 2008 * * The MIT License * * Copyright (c) 2008 Malachi de AElfweald <malachid@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ //package org.eoti.util.size; import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; import java.util.List; public enum Bytes { B("byte"), KB("kilobyte"), MB("megabyte"), GB("gigabyte"), TB("terabyte"), PB("petabyte"), EB("exabyte"), ZB( "zettabyte"), YB("yottabyte"); Bytes(String name) { this.name = name; } private String name; public String getName() { return name; } public BigInteger convertFrom(BigInteger originalAmount, Bytes originalType) { /** * So, B.convertFrom(BigInteger.ONE, YB) * should be used to convert 1 yottabyte to bytes... */ BigInteger currentAmount = originalAmount; int convertTo = ordinal(); int convertFrom = originalType.ordinal(); while (convertTo != convertFrom) { if (convertTo < convertFrom) { currentAmount = currentAmount.shiftLeft(10); convertFrom--; } else { currentAmount = currentAmount.shiftRight(10); convertFrom++; } } return currentAmount; } private static List<Bytes> reversed = reverse(Bytes.values()); private static final BigInteger TWO = BigInteger.valueOf(2); private static final String friendlyFMT = "%s %s"; public static String friendly(long bytes) { return friendly(Bytes.B, BigInteger.valueOf(bytes)); } /** * Convert the specified amount into a human readable (though slightly less accurate) * result. IE: * '4096 B' to '4 KB' * '5080 B' to '5 KB' even though it is really '4 KB + 984 B' */ public static String friendly(Bytes type, BigInteger value) { /** * Logic: * Loop from YB to B * If result = 0, continue * Else, round off * * NOTE: BigIntegers are not reusable, so not point in caching them outside the loop */ for (Bytes newType : reversed) { BigInteger newAmount = newType.convertFrom(value, type); if (newAmount.equals(BigInteger.ZERO)) continue; // Found the right one. Now to round off BigInteger unitBytes = Bytes.B.convertFrom(BigInteger.ONE, newType); BigInteger usedBytes = newAmount.multiply(unitBytes); BigInteger remainingBytes = Bytes.B.convertFrom(value, type).subtract(usedBytes); if (remainingBytes.equals(BigInteger.ZERO)) return String.format(friendlyFMT, newAmount.toString(), newType); if (remainingBytes.equals(value)) return String.format(friendlyFMT, newAmount.toString(), newType); BigInteger halfUnit = unitBytes.divide(TWO); if ((remainingBytes.subtract(halfUnit)).signum() < 0) return String.format(friendlyFMT, newAmount.toString(), newType); return String.format(friendlyFMT, (newAmount.add(BigInteger.ONE)).toString(), newType); } // Give up return String.format(friendlyFMT, value.toString(), type); } public static <T> List<T> reverse(T[] array) { List<T> list = Arrays.asList(array); Collections.reverse(list); return list; } } /* * @(#)BytesTest.java 1.0 Sept 30, 2008 * * The MIT License * * Copyright (c) 2008 Malachi de AElfweald <malachid@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ /* package org.eoti.util.size; import static org.junit.Assert.*; import org.junit.Test; import java.math.BigInteger; */ // 1 YB[yottabyte(s)] = // 1208925819614629174706176 B[byte(s)] // 1180591620717411303424 KB[kilobyte(s)] // 1152921504606846976 MB[megabyte(s)] // 1125899906842624 GB[gigabyte(s)] // 1099511627776 TB[terabyte(s)] // 1073741824 PB[petabyte(s)] // 1048576 EB[exabyte(s)] // 1024 ZB[zettabyte(s)] // 1 YB[yottabyte(s)] /* public class BytesTest { @Test public void YBtoB() { assertEquals("YBtoB", "1208925819614629174706176", convertFrom(Bytes.YB, "1", Bytes.B)); } @Test public void YBtoYB() { assertEquals("YBtoYB", "1", convertFrom(Bytes.YB, "1", Bytes.YB)); } @Test public void BtoB() { assertEquals("BtoB", "1", convertFrom(Bytes.B, "1", Bytes.B)); } @Test public void BtoYB() { assertEquals("BtoYB", "0", convertFrom(Bytes.B, "1", Bytes.YB)); } @Test public void roundUp() { assertEquals("roundUp", "5 KB", Bytes.friendly(Bytes.B, new BigInteger("5080"))); } @Test public void roundDown() { assertEquals("roundDown", "4 KB", Bytes.friendly(Bytes.B, new BigInteger("4588"))); } private String convertFrom(Bytes sourceType, String sourceAmt, Bytes destType) { return destType.convertFrom((new BigInteger(sourceAmt)), sourceType).toString(); } } */