Java에서 바이트 크기를 사람이 읽을 수있는 형식으로 변환하는 방법은 무엇입니까?
Java에서 바이트 크기를 사람이 읽을 수있는 형식으로 변환하는 방법은 무엇입니까? 1024와 마찬가지로 "1Kb"가되어야하고 1024 * 1024는 "1Mb"가되어야합니다.
각 프로젝트에 대해이 유틸리티 방법을 작성하는 데 어려움이 있습니다. 이것을 위해 Apache Commons에 정적 메소드가 있습니까?
여기에 내가 간다 (루프가없고 SI 단위와 이진 단위를 모두 처리합니다).
public static String humanReadableByteCount(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit) return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
출력 예 :
SI BINARY
0: 0 B 0 B
27: 27 B 27 B
999: 999 B 999 B
1000: 1.0 kB 1000 B
1023: 1.0 kB 1023 B
1024: 1.0 kB 1.0 KiB
1728: 1.7 kB 1.7 KiB
110592: 110.6 kB 108.0 KiB
7077888: 7.1 MB 6.8 MiB
452984832: 453.0 MB 432.0 MiB
28991029248: 29.0 GB 27.0 GiB
1855425871872: 1.9 TB 1.7 TiB
9223372036854775807: 9.2 EB 8.0 EiB (Long.MAX_VALUE)
관련 기사 : Java : 사람이 읽을 수있는 형식으로 바이트 크기 형식화
FileUtils.byteCountToDisplaySize(long size)
프로젝트가 의지 할 수 있다면 효과가있을 것입니다 org.apache.commons.io
.
안드로이드 내장 클래스 사용
안드로이드에는 Formatter 클래스가 있습니다. 코드와 비슷한 것만으로 끝납니다.
android.text.format.Formatter.formatShortFileSize(activityContext, bytes);
Like formatFileSize()
이지만 더 짧은 숫자를 생성하려고합니다 (소수를 적게 표시 함).
android.text.format.Formatter.formatFileSize(activityContext, bytes);
콘텐츠 크기를 바이트, 킬로바이트, 메가 바이트 등의 형식으로 지정합니다.
우리는 완전히 느리게하여 피할 수 Math.pow()
와 Math.log()
유닛 사이의 인자 (예를 들어 B, KB, MB 등) 때문에 단순성을 희생하지 않고 방법은 2 ^ 10 1024이다. 이 Long
클래스에는 numberOfLeadingZeros()
크기 값에 속하는 단위를 알려주 는 편리한 메소드가 있습니다.
요점 : 크기 단위의 거리는 10 비트 (1024 = 2 ^ 10)이며 최상위 1 비트의 위치를 의미합니다. 즉, 선행 0 의 수는 10만큼 다릅니다 (바이트 = KB * 1024, KB = MB * 1024 등).
선행 0의 수와 크기 단위의 상관 관계 :
# of leading 0's Size unit
-------------------------------
>53 B (Bytes)
>43 KB
>33 MB
>23 GB
>13 TB
>3 PB
<=2 EB
최종 코드 :
public static String formatSize(long v) {
if (v < 1024) return v + " B";
int z = (63 - Long.numberOfLeadingZeros(v)) / 10;
return String.format("%.1f %sB", (double)v / (1L << (z*10)), " KMGTPE".charAt(z));
}
최근에 같은 질문을했습니다.
기본 답변은 없지만 솔루션으로 살 수 있습니다.
private static final long K = 1024;
private static final long M = K * K;
private static final long G = M * K;
private static final long T = G * K;
public static String convertToStringRepresentation(final long value){
final long[] dividers = new long[] { T, G, M, K, 1 };
final String[] units = new String[] { "TB", "GB", "MB", "KB", "B" };
if(value < 1)
throw new IllegalArgumentException("Invalid file size: " + value);
String result = null;
for(int i = 0; i < dividers.length; i++){
final long divider = dividers[i];
if(value >= divider){
result = format(value, divider, units[i]);
break;
}
}
return result;
}
private static String format(final long value,
final long divider,
final String unit){
final double result =
divider > 1 ? (double) value / (double) divider : (double) value;
return new DecimalFormat("#,##0.#").format(result) + " " + unit;
}
테스트 코드 :
public static void main(final String[] args){
final long[] l = new long[] { 1l, 4343l, 43434334l, 3563543743l };
for(final long ll : l){
System.out.println(convertToStringRepresentation(ll));
}
}
출력 (내 독일어 로케일) :
1 B
4,2 KB
41,4 MB
3,3 GB
편집 : Google Guava 에이 기능을 요청 하는 문제를 열었습니다 . 아마도 누군가가 그것을 지원하려고 할 것입니다.
이것은 aioobe 's answer의 수정 된 버전입니다 .
변경 사항 :
Locale
일부 언어는.
다른 언어,
를 소수점으로 사용하기 때문 입니다.- 사람이 읽을 수있는 코드
private static final String[] SI_UNITS = { "B", "kB", "MB", "GB", "TB", "PB", "EB" };
private static final String[] BINARY_UNITS = { "B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB" };
public static String humanReadableByteCount(final long bytes, final boolean useSIUnits, final Locale locale)
{
final String[] units = useSIUnits ? SI_UNITS : BINARY_UNITS;
final int base = useSIUnits ? 1000 : 1024;
// When using the smallest unit no decimal point is needed, because it's the exact number.
if (bytes < base) {
return bytes + " " + units[0];
}
final int exponent = (int) (Math.log(bytes) / Math.log(base));
final String unit = units[exponent];
return String.format(locale, "%.1f %s", bytes / Math.pow(base, exponent), unit);
}
Android를 사용하는 경우 간단히 Formatter.formatFileSize () 를 사용할 수 있습니다 .
대안으로, 이 인기있는 게시물을 기반으로 한 솔루션 이 있습니다 .
/**
* formats the bytes to a human readable format
*
* @param si true if each kilo==1000, false if kilo==1024
*/
@SuppressLint("DefaultLocale")
public static String humanReadableByteCount(final long bytes,final boolean si)
{
final int unit=si ? 1000 : 1024;
if(bytes<unit)
return bytes+" B";
double result=bytes;
final String unitsToUse=(si ? "k" : "K")+"MGTPE";
int i=0;
final int unitsCount=unitsToUse.length();
while(true)
{
result/=unit;
if(result<unit)
break;
// check if we can go further:
if(i==unitsCount-1)
break;
++i;
}
final StringBuilder sb=new StringBuilder(9);
sb.append(String.format("%.1f ",result));
sb.append(unitsToUse.charAt(i));
if(si)
sb.append('B');
else sb.append('i').append('B');
final String resultStr=sb.toString();
return resultStr;
}
private static final String[] Q = new String[]{"", "K", "M", "G", "T", "P", "E"};
public String getAsString(long bytes)
{
for (int i = 6; i > 0; i--)
{
double step = Math.pow(1024, i);
if (bytes > step) return String.format("%3.1f %s", bytes / step, Q[i]);
}
return Long.toString(bytes);
}
public static String floatForm (double d)
{
return new DecimalFormat("#.##").format(d);
}
public static String bytesToHuman (long size)
{
long Kb = 1 * 1024;
long Mb = Kb * 1024;
long Gb = Mb * 1024;
long Tb = Gb * 1024;
long Pb = Tb * 1024;
long Eb = Pb * 1024;
if (size < Kb) return floatForm( size ) + " byte";
if (size >= Kb && size < Mb) return floatForm((double)size / Kb) + " Kb";
if (size >= Mb && size < Gb) return floatForm((double)size / Mb) + " Mb";
if (size >= Gb && size < Tb) return floatForm((double)size / Gb) + " Gb";
if (size >= Tb && size < Pb) return floatForm((double)size / Tb) + " Tb";
if (size >= Pb && size < Eb) return floatForm((double)size / Pb) + " Pb";
if (size >= Eb) return floatForm((double)size / Eb) + " Eb";
return "???";
}
private String bytesIntoHumanReadable(long bytes) {
long kilobyte = 1024;
long megabyte = kilobyte * 1024;
long gigabyte = megabyte * 1024;
long terabyte = gigabyte * 1024;
if ((bytes >= 0) && (bytes < kilobyte)) {
return bytes + " B";
} else if ((bytes >= kilobyte) && (bytes < megabyte)) {
return (bytes / kilobyte) + " KB";
} else if ((bytes >= megabyte) && (bytes < gigabyte)) {
return (bytes / megabyte) + " MB";
} else if ((bytes >= gigabyte) && (bytes < terabyte)) {
return (bytes / gigabyte) + " GB";
} else if (bytes >= terabyte) {
return (bytes / terabyte) + " TB";
} else {
return bytes + " Bytes";
}
}
바이트 단위를 사용하면 다음과 같이 할 수 있습니다.
long input1 = 1024;
long input2 = 1024 * 1024;
Assert.assertEquals("1 KiB", BinaryByteUnit.format(input1));
Assert.assertEquals("1 MiB", BinaryByteUnit.format(input2));
Assert.assertEquals("1.024 KB", DecimalByteUnit.format(input1, "#.0"));
Assert.assertEquals("1.049 MB", DecimalByteUnit.format(input2, "#.000"));
NumberFormat format = new DecimalFormat("#.#");
Assert.assertEquals("1 KiB", BinaryByteUnit.format(input1, format));
Assert.assertEquals("1 MiB", BinaryByteUnit.format(input2, format));
나는 당신이 이것을 다음과 같이 할 수있게 해주는 저장 장치 라는 또 다른 라이브러리를 작성 했습니다.
String formattedUnit1 = StorageUnits.formatAsCommonUnit(input1, "#");
String formattedUnit2 = StorageUnits.formatAsCommonUnit(input2, "#");
String formattedUnit3 = StorageUnits.formatAsBinaryUnit(input1);
String formattedUnit4 = StorageUnits.formatAsBinaryUnit(input2);
String formattedUnit5 = StorageUnits.formatAsDecimalUnit(input1, "#.00", Locale.GERMAN);
String formattedUnit6 = StorageUnits.formatAsDecimalUnit(input2, "#.00", Locale.GERMAN);
String formattedUnit7 = StorageUnits.formatAsBinaryUnit(input1, format);
String formattedUnit8 = StorageUnits.formatAsBinaryUnit(input2, format);
Assert.assertEquals("1 kB", formattedUnit1);
Assert.assertEquals("1 MB", formattedUnit2);
Assert.assertEquals("1.00 KiB", formattedUnit3);
Assert.assertEquals("1.00 MiB", formattedUnit4);
Assert.assertEquals("1,02 kB", formattedUnit5);
Assert.assertEquals("1,05 MB", formattedUnit6);
Assert.assertEquals("1 KiB", formattedUnit7);
Assert.assertEquals("1 MiB", formattedUnit8);
특정 유닛을 강제 실행하려면 다음을 수행하십시오.
String formattedUnit9 = StorageUnits.formatAsKibibyte(input2);
String formattedUnit10 = StorageUnits.formatAsCommonMegabyte(input2);
Assert.assertEquals("1024.00 KiB", formattedUnit9);
Assert.assertEquals("1.00 MB", formattedUnit10);
이제 단위 형식을 포함하는 라이브러리가 하나 있습니다. 기존의 다른 라이브러리가 Android 용 라이브러리 인 것처럼 보이기 때문에 triava 라이브러리에 추가했습니다 .
3 가지 시스템 (SI, IEC, JEDEC)과 다양한 출력 옵션에서 임의의 정밀도로 숫자를 형식화 할 수 있습니다. 다음은 triava 단위 테스트 의 코드 예제입니다 .
UnitFormatter.formatAsUnit(1126, UnitSystem.SI, "B");
// = "1.13kB"
UnitFormatter.formatAsUnit(2094, UnitSystem.IEC, "B");
// = "2.04KiB"
정확한 킬로, 메가 값 인쇄 (여기서 W = 와트) :
UnitFormatter.formatAsUnits(12_000_678, UnitSystem.SI, "W", ", ");
// = "12MW, 678W"
DecimalFormat을 전달하여 출력을 사용자 정의 할 수 있습니다.
UnitFormatter.formatAsUnit(2085, UnitSystem.IEC, "B", new DecimalFormat("0.0000"));
// = "2.0361KiB"
킬로 또는 메가 값에 대한 임의 작업의 경우 구성 요소로 분할 할 수 있습니다.
UnitComponent uc = new UnitComponent(123_345_567_789L, UnitSystem.SI);
int kilos = uc.kilo(); // 567
int gigas = uc.giga(); // 123
이 게시물을 업데이트하기에는 너무 늦었습니다. 그러나 나는 이것으로 재미있었습니다.
인터페이스를 만듭니다.
public interface IUnits {
public String format(long size, String pattern);
public long getUnitSize();
}
StorageUnits 클래스를 작성하십시오.
import java.text.DecimalFormat;
public class StorageUnits {
private static final long K = 1024;
private static final long M = K * K;
private static final long G = M * K;
private static final long T = G * K;
enum Unit implements IUnits {
TERA_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "TB", pattern);
}
@Override
public long getUnitSize() {
return T;
}
@Override
public String toString() {
return "Terabytes";
}
},
GIGA_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "GB", pattern);
}
@Override
public long getUnitSize() {
return G;
}
@Override
public String toString() {
return "Gigabytes";
}
},
MEGA_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "MB", pattern);
}
@Override
public long getUnitSize() {
return M;
}
@Override
public String toString() {
return "Megabytes";
}
},
KILO_BYTE {
@Override
public String format(long size, String pattern) {
return format(size, getUnitSize(), "kB", pattern);
}
@Override
public long getUnitSize() {
return K;
}
@Override
public String toString() {
return "Kilobytes";
}
};
String format(long size, long base, String unit, String pattern) {
return new DecimalFormat(pattern).format(
Long.valueOf(size).doubleValue() / Long.valueOf(base).doubleValue()
) + unit;
}
}
public static String format(long size, String pattern) {
for(Unit unit : Unit.values()) {
if(size >= unit.getUnitSize()) {
return unit.format(size, pattern);
}
}
return ("???(" + size + ")???");
}
public static String format(long size) {
return format(size, "#,##0.#");
}
}
불러라:
class Main {
public static void main(String... args) {
System.out.println(StorageUnits.format(21885));
System.out.println(StorageUnits.format(2188121545L));
}
}
산출:
21.4kB
2GB
String[] fileSizeUnits = {"bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
public String calculateProperFileSize(double bytes){
String sizeToReturn = "";
int index = 0;
for(index = 0; index < fileSizeUnits.length; index++){
if(bytes < 1024){
break;
}
bytes = bytes / 1024;
}
더 많은 파일 단위를 추가하면 (누락 된 경우) 해당 단위까지의 파일 크기가 표시됩니다 (파일 길이가 너무 긴 경우). System.out.println ( "올바른 형식의 파일 크기 :"+ bytes + ""+ fileSizeUnits [인덱스]); sizeToReturn = String.valueOf (bytes) + ""+ fileSizeUnits [index]; return sizeToReturn; }
위의 Java 정답 답변에 대한 C # .net 항목은 다음과 같습니다. (아래에 더 짧은 코드가있는 다른 것이 있습니다)
public static String BytesNumberToHumanReadableString(long bytes, bool SI1000orBinary1024)
{
int unit = SI1000orBinary1024 ? 1000 : 1024;
if (bytes < unit) return bytes + " B";
int exp = (int)(Math.Log(bytes) / Math.Log(unit));
String pre = (SI1000orBinary1024 ? "kMGTPE" : "KMGTPE")[(exp - 1)] + (SI1000orBinary1024 ? "" : "i");
return String.Format("{0:F1} {1}B", bytes / Math.Pow(unit, exp), pre);
}
기술적으로 말하면 SI 단위를 고수하면이 루틴은 숫자를 정기적으로 사용하는 데 효과적입니다. 전문가의 다른 좋은 답변이 많이 있습니다. gridview에서 숫자의 데이터 바인딩을 수행한다고 가정 해보십시오. 성능 최적화 루틴을 확인하는 것이 좋습니다.
추신 : C # 프로젝트를 수행하는 동안이 질문 / 답변이 Google 검색에서 맨 위에 나타났기 때문에 게시되었습니다.
오프-기회에서 그것은 약간의 시간을 절약하거나 어쩌면 약간의 재미를 위해, 여기에 Go 버전이 있습니다. 편의상 이진 출력 사례 만 포함했습니다.
func sizeOf(bytes int64) string {
const unit = 1024
if bytes < unit {
return fmt.Sprintf("%d B", bytes)
}
fb := float64(bytes)
exp := int(math.Log(fb) / math.Log(unit))
pre := "KMGTPE"[exp-1]
div := math.Pow(unit, float64(exp))
return fmt.Sprintf("%.1f %ciB", fb / div, pre)
}
filename=filedilg.getSelectedFile().getAbsolutePath();
File file=new File(filename);
String disp=FileUtils.byteCountToDisplaySize(file.length());
System.out.println("THE FILE PATH IS "+file+"THIS File SIZE IS IN MB "+disp);
JSR 363 을 사용해 보셨습니까 ? 유니 코드 CLDR ( GitHub : uom-systems ) 과 같은 단위 확장 모듈 은 모든 것을 지원합니다.
MetricPrefix
모든 구현에 포함하거나 BinaryPrefix
(위의 일부 예와 비교하여) 사용할 수 있으며 , 인도 또는 인근 국가에서 거주 및 근무하는 경우 IndianPrefix
(uom-systems의 공통 모듈에서도) "Crore 바이트 "또는"라크 바이트 "도 마찬가지입니다.
당신은 사용할 수 있습니다 StringUtils에 의를 TraditionalBinarPrefix
:
public static String humanReadableInt(long number) {
return TraditionalBinaryPrefix.long2String(number,””,1);
}
이 코드를 C #에서 사용할 수 있습니다.
long Kb = 1024;
long Mb = Kb * 1024;
long Gb = Mb * 1024;
long Tb = Gb * 1024;
long Pb = Tb * 1024;
long Eb = Pb * 1024;
if (size < Kb) return size.ToString() + " byte";
if (size < Mb) return (size / Kb).ToString("###.##") + " Kb.";
if (size < Gb) return (size / Mb).ToString("###.##") + " Mb.";
if (size < Tb) return (size / Gb).ToString("###.##") + " Gb.";
if (size < Pb) return (size / Tb).ToString("###.##") + " Tb.";
if (size < Eb) return (size / Pb).ToString("###.##") + " Pb.";
if (size >= Eb) return (size / Eb).ToString("###.##") + " Eb.";
return "invalid size";
public String humanReadable(long size) {
long limit = 10 * 1024;
long limit2 = limit * 2 - 1;
String negative = "";
if(size < 0) {
negative = "-";
size = Math.abs(size);
}
if(size < limit) {
return String.format("%s%s bytes", negative, size);
} else {
size = Math.round((double) size / 1024);
if (size < limit2) {
return String.format("%s%s kB", negative, size);
} else {
size = Math.round((double)size / 1024);
if (size < limit2) {
return String.format("%s%s MB", negative, size);
} else {
size = Math.round((double)size / 1024);
if (size < limit2) {
return String.format("%s%s GB", negative, size);
} else {
size = Math.round((double)size / 1024);
return String.format("%s%s TB", negative, size);
}
}
}
}
}
ATM_CashWithdrawl
개념 기반을 취하여 생성 된 정확한 정보를 얻으려면 다음 함수를 사용하십시오 .
getFullMemoryUnit(): Total: [123 MB], Max: [1 GB, 773 MB, 512 KB], Free: [120 MB, 409 KB, 304 Bytes]
public static String getFullMemoryUnit(long unit) {
long BYTE = 1024, KB = BYTE, MB = KB * KB, GB = MB * KB, TB = GB * KB;
long KILO_BYTE, MEGA_BYTE = 0, GIGA_BYTE = 0, TERA_BYTE = 0;
unit = Math.abs(unit);
StringBuffer buffer = new StringBuffer();
if ( unit / TB > 0 ) {
TERA_BYTE = (int) (unit / TB);
buffer.append(TERA_BYTE+" TB");
unit -= TERA_BYTE * TB;
}
if ( unit / GB > 0 ) {
GIGA_BYTE = (int) (unit / GB);
if (TERA_BYTE != 0) buffer.append(", ");
buffer.append(GIGA_BYTE+" GB");
unit %= GB;
}
if ( unit / MB > 0 ) {
MEGA_BYTE = (int) (unit / MB);
if (GIGA_BYTE != 0) buffer.append(", ");
buffer.append(MEGA_BYTE+" MB");
unit %= MB;
}
if ( unit / KB > 0 ) {
KILO_BYTE = (int) (unit / KB);
if (MEGA_BYTE != 0) buffer.append(", ");
buffer.append(KILO_BYTE+" KB");
unit %= KB;
}
if ( unit > 0 ) buffer.append(", "+unit+" Bytes");
return buffer.toString();
}
방금 facebookarchive-StringUtils
의 코드를 수정 하여 아래 형식을 얻었습니다. apache.hadoop- 를 사용할 때와 같은 형식StringUtils
getMemoryUnit(): Total: [123.0 MB], Max: [1.8 GB], Free: [120.4 MB]
public static String getMemoryUnit(long bytes) {
DecimalFormat oneDecimal = new DecimalFormat("0.0");
float BYTE = 1024.0f, KB = BYTE, MB = KB * KB, GB = MB * KB, TB = GB * KB;
long absNumber = Math.abs(bytes);
double result = bytes;
String suffix = " Bytes";
if (absNumber < MB) {
result = bytes / KB;
suffix = " KB";
} else if (absNumber < GB) {
result = bytes / MB;
suffix = " MB";
} else if (absNumber < TB) {
result = bytes / GB;
suffix = " GB";
}
return oneDecimal.format(result) + suffix;
}
위 방법의 사용법 예 :
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
int availableProcessors = runtime.availableProcessors();
long heapSize = Runtime.getRuntime().totalMemory();
long heapMaxSize = Runtime.getRuntime().maxMemory();
long heapFreeSize = Runtime.getRuntime().freeMemory();
System.out.format("Total: [%s], Max: [%s], Free: [%s]\n", heapSize, heapMaxSize, heapFreeSize);
System.out.format("getMemoryUnit(): Total: [%s], Max: [%s], Free: [%s]\n",
getMemoryUnit(heapSize), getMemoryUnit(heapMaxSize), getMemoryUnit(heapFreeSize));
System.out.format("getFullMemoryUnit(): Total: [%s], Max: [%s], Free: [%s]\n",
getFullMemoryUnit(heapSize), getFullMemoryUnit(heapMaxSize), getFullMemoryUnit(heapFreeSize));
}
형식을 초과하는 바이트
Total: [128974848], Max: [1884815360], Free: [126248240]
사람이 읽을 수있는 형식으로 시간을 표시하려면이 기능을 사용하십시오 millisToShortDHMS(long duration)
.
'Programming' 카테고리의 다른 글
iOS에서 화면 너비와 높이를 얻는 방법은 무엇입니까? (0) | 2020.02.12 |
---|---|
Swift에서 문자열에 다른 문자열이 포함되어 있는지 어떻게 확인합니까? (0) | 2020.02.12 |
UIDevice uniqueIdentifier 더 이상 사용되지 않음-지금 무엇을해야합니까? (0) | 2020.02.12 |
비표준 글꼴을 웹 사이트에 추가하는 방법은 무엇입니까? (0) | 2020.02.12 |
존재하지 않음 vs 존재하지 않음 (0) | 2020.02.12 |