PDA

Ver la Versión Completa : Formatear tamaño de archivos (B, KB, MB, GB,TB, etc)


Lepe
08-06-2006, 12:41:41
Las rutinas sirven tanto para kilogramos, litros como KB. Se añade una rutina FormatFileSize por comodidad y aprendizaje de uso ;).


uses Windows, SysUtils, Classes, FileCtrl,shellapi,Forms,math; // algunos sobran ;)

type FileUnit = ( B=0, Kb, Mb, Gb, Tb, Auto);
var FileSizeUnit :array[FileUnit ] of string= ('B ', 'KB', 'MB', 'GB','TB', '');

// Lepe:
// formatea el tamaño de un archivo, el string es una de las variables
// declaradas arriba. Usar con jclFileUtils.GetSizeOfFile
function FormatFileSize(const Number:Int64;
const SelectedUnit:FileUnit=Auto):string;
// Lepe:
// formatea cualquier numero en base a unas unidades y el salto
// entre dichas unidades (UnitsDiff)
function FormatNumbers(const Number:Int64;
const BaseUnits:TStrings;
const UnitsDiff:Longint;
const SelectedUnit:Integer=0):string;

implementation
function FormatFileSize(const Number:Int64;
const SelectedUnit:FileUnit =Auto):string;
var units:TStringList;
AutoUnit:FileUnit;
begin
units:= TStringList.Create;
try
units.Add(FileSizeUnit[B]);
units.Add(FileSizeUnit[Kb]);
units.Add(FileSizeUnit[Mb]);
units.Add(FileSizeUnit[gB]);
units.Add(FileSizeUnit[Tb]);
AutoUnit:= SelectedUnit;
if AutoUnit=auto then
while (AutoUnit > b) and (Number < Power(1024,Integer(AutoUnit)))do
Dec(AutoUnit);
Result:= formatnumbers(Number, units,1024,
units.IndexOf(FileSizeUnit[AutoUnit]));
finally
units.Free;
end;
end;



function FormatNumbers(const Number:Int64;
const BaseUnits:TStrings;
const UnitsDiff:Longint;
const SelectedUnit:Integer=0):string;
var Divisor:Extended;
ComaPos, i, ThousandsSep:Integer;
temp:string;
begin
Result := IntToStr(Number);
if Assigned(baseunits) then
if (SelectedUnit <> 0) and (SelectedUnit <= BaseUnits.Count) then
if (UnitsDiff <> 0) then
begin
Divisor := Power(UnitsDiff, Integer(SelectedUnit));
Result := IntToStr(trunc(number / Divisor));

temp := Floattostrf(frac(number / Divisor),ffNumber,3,2);
Result:= Result + Copy(temp,pos(sysutils.DecimalSeparator,temp),3);

end;
{------------------------------------------------------------------------------
No podemos usar format para añadir los puntos de millar, ya que necesita
un Float, que tiene menos precisión que un Int64
---------------añadimos puntos de millar y comas ----------------------------}
ThousandsSep:= 0;
ComaPos:= Pos(Sysutils.DecimalSeparator,Result);
if ComaPos = 0 then
ComaPos := Length(Result)
else
Dec(ComaPos);
for i:= ComaPos downto 2 do
begin
Inc(ThousandsSep);
if (ThousandsSep mod 3 = 0)then
Result:= Copy(Result,1,i-1)+
sysutils.ThousandSeparator+
Copy(Result,i,255);
end;
{-----------------------------fin --------------------------------------------}

if Assigned(baseunits) then
if BaseUnits.Count > 0 then
if (SelectedUnit < BaseUnits.Count) then
Result := Result +' '+BaseUnits[selectedunit];
end;


Para llamar a la rutina:

var s:string;
begin
s:= FormatFileSize(46546466546); // busca la unidad automáticamente

s:= FormatFileSize(46546466546, MB); // resultado en la unidad indicada.
end;

Lepe
08-06-2006, 12:41:42
En FormatFileSize, la línea:

units.Add(FileSizeUnit);

Debe decir:

units.Add(FileSizeUnit[ B]);


El sistema lo ha detectado como una "etiqueta de negrita" y se lo ha comido con patatas :D

PD: No sé editar el truco :D

Saludos

Emilio
08-06-2006, 14:03:01
lepe, ya está solucionado, sin embargo puedes editar tus propios trucos haciendo clic en la imagen de un lapiz que aparece a la derecha en el listado de trucos.

Lepe
08-06-2006, 14:32:04
Asias.