Java에서 바이트 크기를 사람이 읽을 수있는 형식으로 변환하는 방법은 무엇입니까?


556

Java에서 바이트 크기를 사람이 읽을 수있는 형식으로 변환하는 방법은 무엇입니까? 1024처럼 "1Kb"가되어야하고 1024 * 1024는 "1Mb"가되어야합니다.

각 프로젝트에 대해이 유틸리티 방법을 작성하는 데 어려움이 있습니다. 이것을 위해 Apache Commons 에 정적 메소드가 있습니까?


32
표준화 된 단위를 사용하는 경우 1024는 "1KiB"가되고 1024 * 1024는 "1MiB"가됩니다. en.wikipedia.org/wiki/Binary_prefix
Pascal Cuoq

@Pascal :베이스와 유닛을 지정하는 몇 가지 기능 또는 옵션이 있어야합니다.
Aaron Digulla


3
@Pascal Cuoq : 참조 해 주셔서 감사합니다. EU에서 우리는 법에 따라 올바른 접두사를 사용해야한다는 것을 알기 전까지는 알지 못했습니다.
JeremyP

2
@DerMike "이러한 라이브러리가 존재할 때까지"언급했습니다. 이것은 이제 사실이되었습니다. :-) stackoverflow.com/questions/3758606/…
Christian Esken

답변:


1310

재미있는 사실 : 여기에 게시 된 원래 스 니펫은 스택 오버플로에서 가장 많이 복사 된 Java 스 니펫이며 결함이 있습니다. 수정되었지만 지저분 해졌습니다.

이 기사의 전체 기사 : 모든 시간 동안 가장 많이 복사 된 StackOverflow 스 니펫에 결함이 있습니다!

출처 : 바이트 크기를 사람이 읽을 수있는 형식으로 포맷 | 프로그래밍 가이드

SI (1k = 1,000)

public static String humanReadableByteCountSI(long bytes) {
    if (-1000 < bytes && bytes < 1000) {
        return bytes + " B";
    }
    CharacterIterator ci = new StringCharacterIterator("kMGTPE");
    while (bytes <= -999_950 || bytes >= 999_950) {
        bytes /= 1000;
        ci.next();
    }
    return String.format("%.1f %cB", bytes / 1000.0, ci.current());
}

이진수 (1K = 1,024)

public static String humanReadableByteCountBin(long bytes) {
    long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
    if (absB < 1024) {
        return bytes + " B";
    }
    long value = absB;
    CharacterIterator ci = new StringCharacterIterator("KMGTPE");
    for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
        value >>= 10;
        ci.next();
    }
    value *= Long.signum(bytes);
    return String.format("%.1f %ciB", value / 1024.0, ci.current());
}

출력 예 :

                              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)

12
1.0KB를 선호합니다. 그러면 결과에 얼마나 중요한 수치가 나오는지 알 수 있습니다. (이것은 또한 예를 들어 du리눅스 에서 명령 의 동작으로 보인다 .)
aioobe

19
모든 고객은 프로젝트에서 고객이 기본 2 (1024로 나눔)의 값을 원하지만 공통 접두사를 원한다는 점에 유의해야한다고 생각합니다. KiB, MiB, GiB 등이 아닙니다. KB, MB, GB, TB를 사용하십시오.
Borys

27
@Borys "1024"를 의미하기 위해 "KB"를 사용하는 것은 잘못되었습니다. 하지마
endolith

8
독자는 그것을 배울 것입니다. 그들이 잘 모르는 것보다 더 나은 것이 있고 잘못된 것을 배우는 것보다 그것을 배울 수 있습니다. KB에 익숙한 사용자는 1000 명, 익숙하지 않은 사용자는 1024 명을 예상합니다.
kap

16
답변은 완전히 다시 작성되었습니다. 위의 의견 중 상당수가 더 이상 사용되지 않습니다.
aioobe

305

FileUtils.byteCountToDisplaySize(long size)프로젝트가 의지 할 수 있다면 효과가있을 것입니다 org.apache.commons.io.

이 메소드의 JavaDoc


18
이미 프로젝트에 commons-io가 있지만 반올림 동작으로 인해 aioobe의 코드를 사용하게되었습니다 (JavaDoc 링크 참조)
Iravanchi

3
역 작업을 수행하는 유틸리티가 있습니까? 사람이 읽을 수있는 바이트 수에서 바이트 수를 가져 오십니까?
arunmoezhi 2016 년

6
불행히도이 기능은 로케일을 인식하지 않습니다. 예를 들어 프랑스어에서는 바이트 "옥텟"을 항상 호출하므로 100KB 파일을 프랑스어 사용자에게 표시 할 경우 올바른 레이블은 100 Ko입니다.
Tacroy

@Tacroy triava 라이브러리의 UnitFormatter로 옥텟 출력을 얻을 수 있습니다. 바이트, 와트 또는 옥텟에 대한 모든 단위를 전달할 수 있습니다. github.com/trivago/triava 의 예제에서 약간 수정 된 예 : UnitFormatter.formatAsUnit (1126, UnitSystem.SI, "o"); // = "1.13 ko"추가 예제 : stackoverflow.com/questions/3758606/…
Christian Esken

5
이것은
1GB보다 크면

180

안드로이드 내장 클래스 사용

안드로이드에는 Formatter 클래스가 있습니다. 한 줄의 코드 만 있으면 완료됩니다.

android.text.format.Formatter.formatShortFileSize(activityContext, bytes);

그것은 formatFileSize()같지만 더 짧은 숫자를 생성하려고합니다 (소수를 적게 표시 함).

android.text.format.Formatter.formatFileSize(activityContext, bytes);

콘텐츠 크기를 바이트, 킬로바이트, 메가 바이트 등의 형식으로 지정합니다.


12
ANDROID에 대한 최고의 답변이 될 것입니다. 추가 라이브러리가 필요하지 않습니다. +1
dieter

11
나는 당신이 전달해야한다는 사실이 싫어 Context.
Jared Burrows

4
ANDROID에 대한 최선의 답변이어야합니다.
shridutt kothari

5
컨텍스트를 전달하면 사용자의 현재 로케일로 변환됩니다. 그렇지 않으면 매우 유용한 기능이 아닙니다.
phreakhead

7
나는 이것을 알기 전에 받아 들인 대답을 사용하고있었습니다. 참고로 Build.VERSION_CODES.N 및 이전 버전에서는 KB = 1024 바이트, MB = 1,048,576 바이트 등 1024의 제곱이 대신 사용됩니다. O부터 접두사는 SI 시스템의 표준 의미로 사용됩니다. 따라서 kB = 1000 바이트, MB = 1,000,000 바이트 등
HendraWD

57

단위 사이의 요소 (예 : B, KB, MB 등)가 2 ^ 10 인 1024이므로 속도 Math.pow()Math.log()낮추지 않고 속도 와 방법을 사용하지 않아도됩니다. 이 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));
}

24

최근에 같은 질문을했습니다.

파일 크기를 MB, GB 등으로 지정

기본 답변은 없지만 솔루션으로 살 수 있습니다.

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 에이 기능을 요청 하는 문제를 열었습니다 . 아마도 누군가가 그것을 지원하려고 할 것입니다.


2
0이 유효하지 않은 파일 크기 인 이유는 무엇입니까?
aioobe

그것은 (업로드 된 파일의 크기를 표시) 내 유스 케이스에, 그러나 틀림없이 보편적 아니라 그 @aioobe
숀 패트릭 플로이드

마지막 줄을 변경하여 NumberFormat.getFormat ( "#, ## 0. #"). format (result) + ""+ unit; 그것은 GWT에서도 작동합니다! 고마워요, 아직 구아바에는 없습니다.
tom

9

이것은 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);
}

구분 기호에 대해서만 Locale 매개 변수를 전달하는 것은 약간 혼합 된 결과이지만 프랑스어와 같이 바이트에 다른 기호를 사용하는 언어를 설명하기 위해 장치를 현지화하지도 않습니다.
Nzall

@Nzall 옥텟을 의미합니까? Wikipedia는 더 이상 일반적이지 않다고 말합니다. 그렇지 않으면 참조가 있습니까?
Christian Strempfer '29 년

7

Android를 사용하는 경우 android.text.format.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;
    }

또는 코 틀린에서 :

/**
 * formats the bytes to a human readable format
 *
 * @param si true if each kilo==1000, false if kilo==1024
 */
@SuppressLint("DefaultLocale")
fun humanReadableByteCount(bytes: Long, si: Boolean): String? {
    val unit = if (si) 1000.0 else 1024.0
    if (bytes < unit)
        return "$bytes B"
    var result = bytes.toDouble()
    val unitsToUse = (if (si) "k" else "K") + "MGTPE"
    var i = 0
    val unitsCount = unitsToUse.length
    while (true) {
        result /= unit
        if (result < unit || i == unitsCount - 1)
            break
        ++i
    }
    return with(StringBuilder(9)) {
        append(String.format("%.1f ", result))
        append(unitsToUse[i])
        if (si) append('B') else append("iB")
    }.toString()
}

for-loop에 off-by-one 오류가있는 것 같습니다. 나는 그것이해야한다고 생각 unitsCount하지 unitsCount-1.
aioobe

@ aioobe 그러나 이것은 i == unitsCount 일 때 루프가 멈출 수 있음을 의미합니다. i == 6은 "charAt"이 실패 함을 의미합니다 ...
android developer

if(result<unit) break;그 전에 시작됩니다. 걱정 마. (테스트하면 for 루프 조건을 완전히 건너 뛸 수 있음을 알 수 있습니다.)
aioobe

@aioobe 맞습니다. "long"변수 유형을 처리한다는 가정 (정확한) 때문입니다. 또한 단위가 적어도 내가 쓴 내용이라는 가정을 기반으로합니다. 더 적은 단위를 사용하면 이상한 결과가 생성됩니다 (1000보다 큰 값이 아닌 1보다 작은 값을 선호 함).
안드로이드 개발자

@aioobe 맞습니다. 내가 고칠 게 BTW, 알고리즘은 이상한 결과를 제공 할 수도 있습니다. "999999, true"를 인수로 사용하십시오. "1000.0 kB"로 표시되므로 반올림하지만 사람들이 볼 때 1000MB = 1MB로 1MB를 표시 할 수없는 이유는 무엇일까요? 어떻게 처리해야한다고 생각하십니까? String.format 때문이지만 어떻게 수정 해야할지 모르겠습니다.
안드로이드 개발자

6

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);
}

6
  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";
        }
    }

나는 따르기 쉽고 이해하기 쉽기 때문에 이것을 좋아합니다.
Joshua Pinter

6

바이트 단위를 사용하면 다음과 같이 할 수 있습니다.

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);

5
    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 "???";
    }

3

이제 단위 형식이 포함 된 라이브러리가 하나 있습니다. 기존의 다른 라이브러리가 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

2

나는이 게시물을 업데이트 너무 늦게 알아! 그러나 나는 이것으로 재미있었습니다.

인터페이스를 만듭니다.

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

2

오프-기회에서 그것은 약간의 시간을 절약하거나 어쩌면 약간의 재미를 위해, 여기에 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)
}

1
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; }


1

위의 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 검색에서 맨 위에 나타났기 때문에 게시되었습니다.


1

당신은 사용할 수 있습니다 StringUtils에 의를 TraditionalBinarPrefix:

public static String humanReadableInt(long number) {
    return TraditionalBinaryPrefix.long2String(number,””,1);
}

1

조금 오래되었지만 ... org.springframework.util.unit.DataSize는 최소한 계산을 위해이 requriement에 적합 할 수 있습니다. 그러면 간단한 장식자가 할 것입니다.


0
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);

이 답변은 작동하는 동안 @ user601806 의이 스레드에서 이전 답변을 보완합니다. stackoverflow.com/a/4888400/3987745 이 답변을 사용하려면 Apache Commons IO ( commons.apache.org/proper/ commons-io ) 종속성.
Edward Quixote

0

JSR 363 을 사용해 보셨습니까 ? 유니 코드 CLDR ( GitHub : uom-systems ) 과 같은 단위 확장 모듈 은 모든 것을 지원합니다.

MetricPrefix모든 구현에 포함하거나 BinaryPrefix(위의 일부 예와 비교하여) 사용할 수 있으며 인도 또는 인근 국가에서 거주 및 근무하는 경우 IndianPrefix(uom-systems의 공통 모듈에서도) "Crore 바이트 "또는"라크 바이트 "도 마찬가지입니다.


0

이 코드를 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";

0
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);
                }
            }
        }
    }
}

0

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).


0

다음은 @aioobe에서 kotlin으로 변환 한 것입니다

/**
 * https://stackoverflow.com/a/3758880/1006741
 */
fun Long.humanReadableByteCountBinary(): String {
    val b = when (this) {
        Long.MIN_VALUE -> Long.MAX_VALUE
        else -> abs(this)
    }
    return when {
        b < 1024L -> "$this B"
        b <= 0xfffccccccccccccL shr 40 -> "%.1f KiB".format(Locale.UK, this / 1024.0)
        b <= 0xfffccccccccccccL shr 30 -> "%.1f MiB".format(Locale.UK, this / 1048576.0)
        b <= 0xfffccccccccccccL shr 20 -> "%.1f GiB".format(Locale.UK, this / 1.073741824E9)
        b <= 0xfffccccccccccccL shr 10 -> "%.1f TiB".format(Locale.UK, this / 1.099511627776E12)
        b <= 0xfffccccccccccccL -> "%.1f PiB".format(Locale.UK, (this shr 10) / 1.099511627776E12)
        else -> "%.1f EiB".format(Locale.UK, (this shr 20) / 1.099511627776E12)
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.