Autor |
Beitrag |
n-regen
Beiträge: 202
Erhaltene Danke: 2
|
Verfasst: Mi 10.09.08 11:52
Hallo!
Ich habe eine Funktion (keine Unit!) geschrieben, die aus einem Int64 mit einer Dateigröße einen String macht und dabei den Wert soweit herunterrechnet, dass er in der größten Einheit ausgegebn wird, in der er nicht als 0,xy-Zahl erscheint.
Also beispielsweise:
- 0 -> 0 Bytes
- 1023 -> 1023 Bytes
- 1024 -> 1,00 KiloByte
- 1048576 -> 1,00 MegaByte
- usw.
Die Funktion rechnet bis TeraBytes. Also käme bei FileSize=1125899906842624, als Ergebnis "1024 TeraBytes" raus.
Man kann außerdem über den Boolean-Wert "LongText" bestimmen, ob im String z.B. "MegaBytes" oder "MB" stehen soll.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35:
| function FileSizeToStr(FileSize: Int64; LongText:Boolean=False):String; begin if FileSize < 1024 then begin if LongText then Result := IntToStr(FileSize)+' Bytes' else Result := IntToStr(FileSize)+' B'; end; if (FileSize >= 1024) and (FileSize < 1048576) then begin if LongText then Result := FloatToStrF(FileSize / 1024, ffNumber, 15, 2)+' KiloBytes' else Result := FloatToStrF(FileSize / 1024, ffNumber, 15, 2)+' KB'; end; if (FileSize >= 1048576) and (FileSize < 1073741824) then begin if LongText then Result := FloatToStrF(FileSize / 1048576, ffNumber, 15, 2)+' MegaBytes' else Result := FloatToStrF(FileSize / 1048576, ffNumber, 15, 2)+' MB'; end; if (FileSize >= 1073741824) and (FileSize < 1099511627776) then begin if LongText then Result := FloatToStrF(FileSize / 1073741824, ffNumber, 15, 2)+' GigaBytes' else Result := FloatToStrF(FileSize / 1073741824, ffNumber, 15, 2)+' GB'; end; if (FileSize >= 1099511627776) then begin if LongText then Result := FloatToStrF(FileSize / 1099511627776, ffNumber, 15, 2)+' TeraBytes' else Result := FloatToStrF(FileSize / 1099511627776, ffNumber, 15, 2)+' TB'; end; if (Result[1] = '1') and (Result[2] = ',') and LongText then Result := Copy(Result, 0, Length(Result)-1); end; |
Ich hoffe, dass irgendjemand diese Funktion brauchen kann und bin natürlich für Verbesserungswünsche offen.
Nils
Zuletzt bearbeitet von n-regen am Mi 10.09.08 13:53, insgesamt 1-mal bearbeitet
|
|
Hidden
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mi 10.09.08 12:43
Hi,
Ich habe deinen Quelltext mal nachformatiert und ein wenig übersichtlicher gemacht. Kann noch optimiert werden, ich wollte möglichst wenig ändern, daher die unnötigen Zwischenvariablen.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51:
| function FileSizeToStr(FileSize: Int64; LongText:Boolean=False): String; const LongNames: Array[0..4] of String = ('Bytes', 'KiloBytes', 'MegaBytes', 'GigaBytes', 'TeraBytes'); ShortNames: Array[0..4] of String = ('B', 'KB', 'MB', 'GB', 'TB'); var RestSize: Int64; MultiFactor: Int64; DataUnit: Integer; DataUnitName: String; begin DataUnit := 0; RestSize := FileSize; While FileSize >= 1024 do begin RestSize := RestSize div 1024; MultiFactor := MultiFactor * 1024; Inc(DataUnit); end; if LongText then DataUnitName := LongNames[DataUnit] else DataUnitName := ShortNames[DataUnit]; Result := FloatToStrF(FileSize / MultiFactor, ffNumber, 15, 2) + ' ' + DataUnitName; if (Result[1] = '1') and (Result[2] = ',') then Result := Copy(Result, 0, Length(Result) - 1); end; |
Edit: Aso, fehlt noch eine Austrittsbedingung aus der Schleife, wenn Terabyte erreicht sind.
E2: Kommentare drangemacht
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 10.09.08 12:48
Moin!
Hier mein Vorschlag:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26:
| function PrettyFileSize(const AFileSize: Int64; ADecimals: Integer = 0; const ALongUnit: Boolean = FALSE): String; const Units: array[0..5,Boolean] of String = ( ('B','Byte'), ('KB','KiloByte'), ('MB','MegaByte'), ('GB','GigaByte'), ('TB','TeraByte'), ('PB','PetaByte') ); var TempSize, UnitValue: Int64; UnitIndex: Integer; begin TempSize := AFileSize; UnitValue := 1; UnitIndex := 0; while ((TempSize shr 10) > 0) and (UnitIndex < High(Units)) do begin TempSize := TempSize shr 10; UnitValue := UnitValue shl 10; Inc(UnitIndex); end; if (UnitIndex = 0) then ADecimals := 0; Result := Format('%.*f %s',[ADecimals,AFileSize/UnitValue,Units[UnitIndex,ALongUnit]]); end; | cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Hidden
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mi 10.09.08 12:50
Narses hat folgendes geschrieben: | Units: array[0..5, Boolean] of String |
Wusste garnicht, dass das möglich ist
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
n-regen
Beiträge: 202
Erhaltene Danke: 2
|
Verfasst: Mi 10.09.08 13:24
So viel, wie man an dieser Funktion verändern und verbessern kann, könnte man die glatt als Beispiel in einem Lehrbuch hernehmen!
Freut mich jedenfalls, dass sich jemand dafür interessiert.
Nils
|
|
Hidden
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mi 10.09.08 13:36
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
n-regen
Beiträge: 202
Erhaltene Danke: 2
|
Verfasst: Mi 10.09.08 13:50
Hidden hat folgendes geschrieben: | Jemand Lust, das in Asm-Code zu übersetzen und, die Veröffentlichung zu übernehmen? |
Wieso Assembler (das meinst du doch mit Asm, oder?)?
Und in den meisten Delphi-Büchern kommt irgendwo was vor: "Was könnte man an dieser Prozedur/Funktion noch besser machen?"
Und für sowas wäre diese Funktion eben gut.
EDIT: Mir ist noch ein Fehler aufgefallen:
Statt
Delphi-Quelltext 1: 2:
| if (Result[1] = '1') and (Result[2] = ',') then Result := Copy(Result, 0, Length(Result)-1); |
muss es
Delphi-Quelltext 1: 2:
| if (Result[1] = '1') and (Result[2] = ',') and LongText then Result := Copy(Result, 0, Length(Result)-1); |
heißen.
Sonst entfernt er nicht nur das s von Bytes, wenn der Ausgabe-String mit 1, anfängt, sondern unter Umständen auch das B von MB o.ä.
|
|
Hidden
Beiträge: 2242
Erhaltene Danke: 55
Win10
VS Code, Delphi 2010 Prof.
|
Verfasst: Mi 10.09.08 14:36
Müsste der Startindex bei Copy nicht 1 sein?
Edit: Würde Gausi's Version nicht bei anderen Boolean-Werten als true und false 'ne Exception werfen?
mfG,
_________________ Centaur spears can block many spells, but no one tries to block if they see that the spell is a certain shade of green. For this purpose it is useful to know some green stunning hexes. (HPMoR)
|
|
BenBE
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: Mi 10.09.08 15:13
Hier ist auch noch ein semantischer Fehler drin
1 000 000 Bytes = 1 MB
1 048 576 Bytes = 1 MiB
Das gilt genauso für die Langfassungen
vgl. xkcd.com/394/
Ach ja: EiB fehlt auch noch bei den Einheiten
_________________ Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
|
|
Narses
Beiträge: 10182
Erhaltene Danke: 1255
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 10.09.08 18:08
Moin!
Hidden hat folgendes geschrieben: | Müsste der Startindex bei Copy nicht 1 sein? |
Würde ich auch sagen.
Hidden hat folgendes geschrieben: | Edit: Würde Gausi's Version nicht bei anderen Boolean-Werten als true und false 'ne Exception werfen? |
a) Was hat Gausi damit zu tun?
b) Welche Werte für den Delphi-Datentyp Boolean kennst du noch, ausser [True, False]?
BenBE hat folgendes geschrieben: | Hier ist auch noch ein semantischer Fehler drin |
Nun, das liegt im Auge des Betrachters, der bevorzugten Norm oder der historischen Herleitung... In meinen Augen ist KB einfach logischer, also KiBiByte&Co und abgesehen davon gefällt es mir besser...
BenBE hat folgendes geschrieben: | Ach ja: EiB fehlt auch noch bei den Einheiten |
Ist ja zum Glück Open-Source...
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
n-regen
Beiträge: 202
Erhaltene Danke: 2
|
Verfasst: Mi 10.09.08 18:14
BenBE hat folgendes geschrieben: | Hier ist auch noch ein semantischer Fehler drin
[...]
Ach ja: EiB fehlt auch noch bei den Einheiten |
1. finde ich die griechischen Einheiten wesentlich klangvoller als die ver-i-ten, neuen Einheiten.
2. habe ich im Eingangspost darauf hingewiesen, dass bei Terybyte - nein nicht Tibibyte ( ) - Schluss ist.
Und wer hat schon eine Datei/einen Ordner, der mehrere Exabyte groß ist.
Nebenbei bemerkt kommen nach Terabyte erstmal Petabyte (siehe u.a. Wikipedia).
|
|
|