Gostaria de saber se o .NET oferece uma maneira limpa de fazer isso:
int64 x = 1000000;
string y = null;
if (x / 1024 == 0) {
y = x + " bytes";
}
else if (x / (1024 * 1024) == 0) {
y = string.Format("{0:n1} KB", x / 1024f);
}
etc ...
Esta é uma maneira bastante concisa de fazer isso:
static readonly string[] SizeSuffixes =
{ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
static string SizeSuffix(Int64 value, int decimalPlaces = 1)
{
if (decimalPlaces < 0) { throw new ArgumentOutOfRangeException("decimalPlaces"); }
if (value < 0) { return "-" + SizeSuffix(-value); }
if (value == 0) { return string.Format("{0:n" + decimalPlaces + "} bytes", 0); }
// mag is 0 for bytes, 1 for KB, 2, for MB, etc.
int mag = (int)Math.Log(value, 1024);
// 1L << (mag * 10) == 2 ^ (10 * mag)
// [i.e. the number of bytes in the unit corresponding to mag]
decimal adjustedSize = (decimal)value / (1L << (mag * 10));
// make adjustment when the value is large enough that
// it would round up to 1000 or more
if (Math.Round(adjustedSize, decimalPlaces) >= 1000)
{
mag += 1;
adjustedSize /= 1024;
}
return string.Format("{0:n" + decimalPlaces + "} {1}",
adjustedSize,
SizeSuffixes[mag]);
}
E aqui está a implementação original que sugeri, que pode ser um pouco mais lenta, mas um pouco mais fácil de seguir:
static readonly string[] SizeSuffixes =
{ "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
static string SizeSuffix(Int64 value, int decimalPlaces = 1)
{
if (value < 0) { return "-" + SizeSuffix(-value); }
int i = 0;
decimal dValue = (decimal)value;
while (Math.Round(dValue, decimalPlaces) >= 1000)
{
dValue /= 1024;
i++;
}
return string.Format("{0:n" + decimalPlaces + "} {1}", dValue, SizeSuffixes[i]);
}
Console.WriteLine(SizeSuffix(100005000L));
Uma coisa a ter em mente - na notação SI, "kilo" geralmente usa uma letra k minúscula, enquanto todas as unidades maiores usam uma letra maiúscula. O Windows usa KB, MB, GB, então usei KB acima, mas você pode considerar kB.
if (value == 0) { return "0"; }
cheque dentro da função.Confira o ByteSize biblioteca. É o
System.TimeSpan
para bytes!Ele lida com a conversão e formatação para você.
Ele também faz representação e análise de strings.
fonte
Como todo mundo está postando seus métodos, decidi postar o método de extensão que geralmente uso para isso:
EDIT: adicionadas variantes int / long ... e corrigido um erro de digitação copypasta ...
fonte
Eu iria resolver isso usando
Extension methods
,Math.Pow
function eEnums
:e usá-lo como:
fonte
A versão resumida da resposta mais votada tem problemas com os valores de TB.
Eu ajustei apropriadamente para lidar também com os valores tb e ainda sem um loop e também adicionei uma pequena verificação de erros para valores negativos. Esta é minha solução:
fonte
Não. Principalmente porque é uma necessidade bastante específica e existem muitas variações possíveis. (É "KB", "Kb" ou "Ko"? Tem um megabyte de 1024 * 1024 bytes ou 1024 * 1000 bytes? - sim, alguns lugares usam isso!)
fonte
Aqui está uma opção que é mais fácil de estender do que a sua, mas não, não há nenhuma incluída na própria biblioteca.
fonte
Esta é uma maneira de fazer isso também (o número 1073741824.0 é de 1024 * 1024 * 1024 também conhecido como GB)
fonte
A resposta de @Servy foi boa e sucinta. Acho que pode ser ainda mais simples?
fonte
Baseado na solução elegante do NeverHopeless:
Talvez haja comentários excessivos, mas tendo a deixá-los para evitar cometer os mesmos erros em futuras visitas ...
fonte
Não.
Mas você pode implementar assim;
Também verifique Como converter corretamente o tamanho do arquivo em bytes em mega ou gigabytes?
fonte
Combinei algumas das respostas aqui em dois métodos que funcionam muito bem. O segundo método abaixo irá converter de uma string de bytes (como 1.5.1 GB) de volta para bytes (como 1621350140) como um valor de tipo longo. Espero que isso seja útil para outras pessoas que procuram uma solução para converter bytes em uma string e de volta em bytes.
fonte
float.Parse
paradouble
?Eu sei que este é um tópico antigo. mas talvez alguém procure uma solução. E aqui está o que eu uso e a maneira mais fácil
fonte
E se:
Por exemplo, ligue como
Irá resultar em saída
fonte
Eu escolhi a solução JerKimballs e gostei disso. No entanto, gostaria de acrescentar / salientar que se trata de fato de uma questão controversa como um todo. Em minha pesquisa (por outras razões), encontrei as seguintes informações.
Quando pessoas normais (ouvi dizer que existem) falam de gigabytes, elas se referem ao sistema métrico em que 1000 à potência de 3 do número original de bytes == o número de gigabytes. No entanto, é claro que há os padrões IEC / JEDEC que são bem resumidos na wikipedia, que em vez de 1000 elevado a x eles têm 1024. O que para dispositivos de armazenamento físico (e eu acho lógico como Amazon e outros) significa um diferença cada vez maior entre métrica e IEC. Assim, por exemplo, 1 TB == 1 terabyte métrico é 1000 elevado à potência de 4, mas a IEC oficialmente denomina o número semelhante como 1 TiB, tebibyte como 1024 elevado à potência de 4. Mas, infelizmente, em aplicações não técnicas (eu faria ir pelo público) a norma é métrica, e no meu próprio aplicativo para uso interno atualmente eu explico a diferença na documentação. Mas, para fins de exibição, não ofereço nada além de métricas. Internamente, embora não seja relevante em meu aplicativo, eu apenas armazeno bytes e faço o cálculo para exibição.
Como uma observação lateral, acho um tanto sem brilho que o .Net framework AFAIK (e estou frequentemente errado, graças aos poderes que são), mesmo em sua encarnação 4.5, não contém nada sobre isso em nenhuma biblioteca interna. Seria de se esperar que uma biblioteca de código aberto de algum tipo fosse NuGettable em algum momento, mas admito que isso é uma pequena implicância. Por outro lado, System.IO.DriveInfo e outros também possuem apenas bytes (desde que), o que é bastante claro.
fonte
https://github.com/logary/logary/blob/master/src/Logary/DataModel.fs#L832-L837
fonte
fonte
Que tal alguma recursão:
Então você pode chamá-lo de:
fonte
Conforme postado acima, a recursão é a forma preferida, com a ajuda do logaritmo.
A função a seguir tem 3 argumentos: a entrada, a restrição de dimensão da saída, que é o terceiro argumento.
Agora vamos converter 12 GB de RAM em várias unidades:
fonte
Eu uso isso para Windows (prefixos binários):
fonte
Eu incorporei isso (com pouca ou nenhuma modificação) em um conversor UWP DataBinding para meu projeto e pensei que também poderia ser útil para outros.
O código é:
Para usá-lo, adicione um recurso local ao seu UserControl ou Page XAML:
Faça referência a ele em um modelo de vinculação de dados ou instância de vinculação de dados:
E ei pronto. A mágica acontece.
fonte