.NET을 사용하여 사람이 읽을 수있는 파일 크기를 바이트 약어로 얻으려면 어떻게해야합니까?
예 : 7,326,629 입력을 받고 6.98MB 표시
답변
이 방법은 가장 효율적인 방법은 아니지만 로그 수학에 익숙하지 않은 경우 쉽게 읽을 수 있으며 대부분의 시나리오에 충분히 빠릅니다.
string[] sizes = { "B", "KB", "MB", "GB", "TB" };
double len = new FileInfo(filename).Length;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1) {
order++;
len = len/1024;
}
// Adjust the format string to your preferences. For example "{0:0.#}{1}" would
// show a single decimal place, and no space.
string result = String.Format("{0:0.##} {1}", len, sizes[order]);
답변
로그를 사용하여 문제를 해결하는 중 ….
static String BytesToString(long byteCount)
{
string[] suf = { "B", "KB", "MB", "GB", "TB", "PB", "EB" }; //Longs run out around EB
if (byteCount == 0)
return "0" + suf[0];
long bytes = Math.Abs(byteCount);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
return (Math.Sign(byteCount) * num).ToString() + suf[place];
}
또한 C #에서도 변환 할 수 있어야합니다. 또한 가독성을 위해 소수점 이하 1 자리로 반올림했습니다.
기본적으로 Base 1024에서 소수점 이하 자릿수를 결정한 다음 1024 ^ 소수 자리로 나눕니다.
일부 사용 및 출력 샘플 :
Console.WriteLine(BytesToString(9223372036854775807)); //Results in 8EB
Console.WriteLine(BytesToString(0)); //Results in 0B
Console.WriteLine(BytesToString(1024)); //Results in 1KB
Console.WriteLine(BytesToString(2000000)); //Results in 1.9MB
Console.WriteLine(BytesToString(-9023372036854775807)); //Results in -7.8EB
편집 : math.floor를 놓친 것으로 지적되었으므로 통합했습니다. (Convert.ToInt32는 자르지 않고 반올림을 사용하므로 플로어가 필요합니다.) 캐치 주셔서 감사합니다.
Edit2 : 음수 크기와 0 바이트 크기에 대한 몇 가지 의견이 있었 으므로이 두 가지 경우를 처리하도록 업데이트되었습니다.
답변
요청 된 기능의 테스트되고 상당히 최적화 된 버전이 여기에 게시됩니다.
소스 코드:
// Returns the human-readable file size for an arbitrary, 64-bit file size
// The default format is "0.### XB", e.g. "4.2 KB" or "1.434 GB"
public string GetBytesReadable(long i)
{
// Get absolute value
long absolute_i = (i < 0 ? -i : i);
// Determine the suffix and readable value
string suffix;
double readable;
if (absolute_i >= 0x1000000000000000) // Exabyte
{
suffix = "EB";
readable = (i >> 50);
}
else if (absolute_i >= 0x4000000000000) // Petabyte
{
suffix = "PB";
readable = (i >> 40);
}
else if (absolute_i >= 0x10000000000) // Terabyte
{
suffix = "TB";
readable = (i >> 30);
}
else if (absolute_i >= 0x40000000) // Gigabyte
{
suffix = "GB";
readable = (i >> 20);
}
else if (absolute_i >= 0x100000) // Megabyte
{
suffix = "MB";
readable = (i >> 10);
}
else if (absolute_i >= 0x400) // Kilobyte
{
suffix = "KB";
readable = i;
}
else
{
return i.ToString("0 B"); // Byte
}
// Divide by 1024 to get fractional value
readable = (readable / 1024);
// Return formatted number with suffix
return readable.ToString("0.### ") + suffix;
}
답변
[DllImport ( "Shlwapi.dll", CharSet = CharSet.Auto )]
public static extern long StrFormatByteSize (
long fileSize
, [MarshalAs ( UnmanagedType.LPTStr )] StringBuilder buffer
, int bufferSize );
/// <summary>
/// Converts a numeric value into a string that represents the number expressed as a size value in bytes, kilobytes, megabytes, or gigabytes, depending on the size.
/// </summary>
/// <param name="filelength">The numeric value to be converted.</param>
/// <returns>the converted string</returns>
public static string StrFormatByteSize (long filesize) {
StringBuilder sb = new StringBuilder( 11 );
StrFormatByteSize( filesize, sb, sb.Capacity );
return sb.ToString();
}
보낸 사람 : http://www.pinvoke.net/default.aspx/shlwapi/StrFormatByteSize.html
답변
어떤 종류의 루프 나 음의 크기 지원없이 파일을 스키닝하는 또 다른 방법 (파일 크기 델타와 같은 것들에 의미가 있음) :
public static class Format
{
static string[] sizeSuffixes = {
"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
public static string ByteSize(long size)
{
Debug.Assert(sizeSuffixes.Length > 0);
const string formatTemplate = "{0}{1:0.#} {2}";
if (size == 0)
{
return string.Format(formatTemplate, null, 0, sizeSuffixes[0]);
}
var absSize = Math.Abs((double)size);
var fpPower = Math.Log(absSize, 1000);
var intPower = (int)fpPower;
var iUnit = intPower >= sizeSuffixes.Length
? sizeSuffixes.Length - 1
: intPower;
var normSize = absSize / Math.Pow(1000, iUnit);
return string.Format(
formatTemplate,
size < 0 ? "-" : null, normSize, sizeSuffixes[iUnit]);
}
}
다음은 테스트 스위트입니다.
[TestFixture] public class ByteSize
{
[TestCase(0, Result="0 B")]
[TestCase(1, Result = "1 B")]
[TestCase(1000, Result = "1 KB")]
[TestCase(1500000, Result = "1.5 MB")]
[TestCase(-1000, Result = "-1 KB")]
[TestCase(int.MaxValue, Result = "2.1 GB")]
[TestCase(int.MinValue, Result = "-2.1 GB")]
[TestCase(long.MaxValue, Result = "9.2 EB")]
[TestCase(long.MinValue, Result = "-9.2 EB")]
public string Format_byte_size(long size)
{
return Format.ByteSize(size);
}
}
답변
체크 아웃 ByteSize의 라이브러리를. 그것은이다 System.TimeSpan
바이트!
변환 및 서식을 처리합니다.
var maxFileSize = ByteSize.FromKiloBytes(10);
maxFileSize.Bytes;
maxFileSize.MegaBytes;
maxFileSize.GigaBytes;
또한 문자열 표현 및 구문 분석도 수행합니다.
// ToString
ByteSize.FromKiloBytes(1024).ToString(); // 1 MB
ByteSize.FromGigabytes(.5).ToString(); // 512 MB
ByteSize.FromGigabytes(1024).ToString(); // 1 TB
// Parsing
ByteSize.Parse("5b");
ByteSize.Parse("1.55B");
답변
다음 방법을 사용하고 싶습니다 (대부분의 경우 충분하지만 최대 테라 바이트를 지원하지만 쉽게 확장 할 수 있습니다).
private string GetSizeString(long length)
{
long B = 0, KB = 1024, MB = KB * 1024, GB = MB * 1024, TB = GB * 1024;
double size = length;
string suffix = nameof(B);
if (length >= TB) {
size = Math.Round((double)length / TB, 2);
suffix = nameof(TB);
}
else if (length >= GB) {
size = Math.Round((double)length / GB, 2);
suffix = nameof(GB);
}
else if (length >= MB) {
size = Math.Round((double)length / MB, 2);
suffix = nameof(MB);
}
else if (length >= KB) {
size = Math.Round((double)length / KB, 2);
suffix = nameof(KB);
}
return $"{size} {suffix}";
}
C # 6.0 (2015) 용으로 작성되었으므로 이전 버전의 경우 약간 편집해야 할 수 있습니다.