![]() |
Grössenangabe automatische Umwandlung
Hallo Wissende,
ich bin auf der Suche nach einer Funktion, welcher man die Größe einer Datei in Byte übergibt und die dann die Bytegröße, Größe in KB, MB, GB oder TB ausgibt mit der entsprechenden Größenangabe. Kennt jemand von euch so eine Standardfunktion, oder muß ich mir das was selbst basteln? Schöne Grüße Euer GreenHorn |
Re: Grössenangabe automatische Umwandlung
na das sollte doch eine einfache rechnung bewerkstelligen, wenn man weiss wieviele bytes ein kbyte hat ;-)
|
Re: Grössenangabe automatische Umwandlung
Ganz so einfach ist es halt nicht, da man noch entsprechende Regeln mit berücksichtigen muss, ab wann man z.B. zur anderen Größenordnung übergeht ohne daß man zu ungenau ist. Da dies aber sehr häufig in Windows zu sehen ist, wie sich die Einheiten ändern, sollte eigentlich eine Standardfunktion hierfür bestehen. Soll ja auch stimmig sein. Fängt ja alleine schon mal an, wieviel ist ein kB 1000 oder 1024 Byte?
Euer GreenHorn |
Re: Grössenangabe automatische Umwandlung
Zitat:
|
Re: Grössenangabe automatische Umwandlung
Zitat:
Zitat:
Zitat:
![]() |
Re: Grössenangabe automatische Umwandlung
Delphi-Quellcode:
es ginge auch über eine Schleife zu berechnen, aber das ist so eine der schnellsten Möglichkeiten
Function SizeToString(Const Size: Int64): String;
Begin If Size < 1000 Then Result := Format('%d B', [Size]) Else If Size < 10235 Then Result := Format('%.2n KB', [Size / 1024]) Else If Size < 102349 Then Result := Format('%.1n KB', [Size / 1024]) Else If Size < 1023488 Then Result := Format('%.0n KB', [Size / 1024]) Else If Size < 10480518 Then Result := Format('%.2n MB', [Size / 1048576]) Else If Size < 104805172 Then Result := Format('%.1n MB', [Size / 1048576]) Else If Size < 1048051712 Then Result := Format('%.0n MB', [Size / 1048576]) Else If Size < 10732049531 Then Result := Format('%.2n GB', [Size / 1073741824]) Else If Size < 107320495309 Then Result := Format('%.1n GB', [Size / 1073741824]) Else If Size < 1073204953088 Then Result := Format('%.0n GB', [Size / 1073741824]) Else If Size < 10989618719622 Then Result := Format('%.2n TB', [Size / 1099511627776]) Else If Size < 109896187196212 Then Result := Format('%.1n TB', [Size / 1099511627776]) Else If Size < 1098961871962112 Then Result := Format('%.0n TB', [Size / 1099511627776]) Else If Size < 11253369568892027 Then Result := Format('%.2n PB', [Size / 1125899906842624]) Else If Size < 112533695688920269 Then Result := Format('%.1n PB', [Size / 1125899906842624]) Else If Size < 1125336956889202688 Then Result := Format('%.0n PB', [Size / 1125899906842624]) Else Result := Format('%.2n EB', [Size / 1152921504606846976]); End; falls sich wer über die "krummen" Zahlen wundert, diese sind so gewählt, daß der Wert immer mit maximal 3 Stellen (Vor- und Nachkomma) und in der optimalsten, dazupassenden Skalierung dargestellt wird. gerechnet mit 1024, damit es zu den Werten im Explorer paßt (ja, ich kenn das 1000er-Besteben, aber ich halte mich ans gängige Verhalten des BS) !!! Achtung: wenn am Rundungsverhalten der FPU rumgespielt wurde, muß/sollte es für diese Funktion wieder zurückgestellt werden, oder man muß dieses auch noch mit hier einbauen. |
Re: Grössenangabe automatische Umwandlung
|
Re: Grössenangabe automatische Umwandlung
Dank Euch. Werde mal auf die Lib von himitsu zurückgreifen. Wenn jemand noch etwas mehr Standardkonformes hat, bin ich da nicht gegen abgeneigt.
Schöne Grüße Euer GreenHorn |
Re: Grössenangabe automatische Umwandlung
Dieser Code ist theoretisch so optimiert, daß es maximal 3 Zahlen im Ergebnis gibt (abgesehn von stsFull)
Delphi-Quellcode:
Hab grad kein Delphi hier, also ist es noch komplett ungetestet.
Type TSTSFormat = (sts2, sts10, sts2Long, sts10Long, stsFull);
Function SizeToString(Const Size: Int64; SFormat: TSizeFormat): String; Const D: Array[0..17] of Integer = (1000, 10235, 102349, 1023488, 10480518, 104805172, 1048051712, 10732049531, 107320495309, 1073204953088, 10989618719622, 109896187196212, 1098961871962112, 11253369568892027, 112533695688920269, 1125336956889202688, 0); S: Array[sts2..sts10Long] of Array[0..7] of String = (('%.*n B', '%.*n KB', '%.*n MB', '%.*n GB', '%.*n TB', '%.*n PB', '%.*n EB'), ('%.*n B', '%.*n KiB', '%.*n MiB', '%.*n GiB', '%.*n TiB', '%.*n PiB', '%.*n EiB'), ('%.*n Byte', '%.*n Kilobyte', '%.*n Megabyte', '%.*n Gigabyte', '%.*n Terabyte', '%.*n Petabyte', '%.*n Exabyte'), ('%.*n Byte', '%.*n Kibibyte', '%.*n Mebibyte', '%.*n Gibibyte', '%.*n Tebibyte', '%.*n Pebibyte', '%.*n Exbibyte'); X: Array[0..7] of Integer = (1, 1024, 1048576, 1073741824, 1099511627776, 1125899906842624, 1152921504606846976); Var i: Integer; Begin If SFormat < stsFull Then Begin i := 0; While (i < 17) and (Size < D[i]) do Inc(i); Result := Format(S[SFormat, (i + 2) div 3], [2 - ((i + 2) mod 3), Size / X[(i + 2) div 3]]); Else Result := Format(S[sts2Long, 0], [Size / 1]); End; |
Re: Grössenangabe automatische Umwandlung
Liste der Anhänge anzeigen (Anzahl: 1)
OK, abgesehn von ein paar Denkfehlern und dem Verzählen bei den Arraygrößen ...
sollte es jetzt gehn und es sollte für jeden was dabei sein :angel:
Delphi-Quellcode:
Wie gesagt, es wird immer auf maximal 3 Stellen gerundet angezeigt.
Type TSTSFormat = (stsShort, stsLong, sts2, sts2Long, sts10, sts10Long, stsFull);
Function SizeToString(Const Size: Int64; SFormat: TSTSFormat; Const ErrorStr: String = ''): String; Const D: Array[Boolean, 0..16] of Int64 = ((1000, 10235, 102349, 1023488, 10480518, 104805172, 1048051712, 10732049531, 107320495309, 1073204953088, 10989618719622, 109896187196212, 1098961871962112, 11253369568892027, 112533695688920269, 1125336956889202688, 0), (1000, 9995, 99950, 999500, 9995000, 99950000, 999500000, 9995000000, 99950000000, 999500000000, 9995000000000, 99950000000000, 999500000000000, 9995000000000000, 99950000000000000, 999500000000000000, 0)); S: Array[sts2..sts10Long] of Array[0..6] of String = (('%.*n B', '%.*n KiB', '%.*n MiB', '%.*n GiB', '%.*n TiB', '%.*n PiB', '%.*n EiB'), ('%.*n Byte', '%.*n Kibibyte', '%.*n Mebibyte', '%.*n Gibibyte', '%.*n Tebibyte', '%.*n Pebibyte', '%.*n Exbibyte'), ( '%.*n B', '%.*n KB', '%.*n MB', '%.*n GB', '%.*n TB', '%.*n PB', '%.*n EB'), ('%.*n Byte', '%.*n Kilobyte', '%.*n Megabyte', '%.*n Gigabyte', '%.*n Terabyte', '%.*n Petabyte', '%.*n Exabyte')); X: Array[Boolean, 0..6] of Int64 = ((1, 1024, 1048576, 1073741824, 1099511627776, 1125899906842624, 1152921504606846976), (1, 1000, 1000000, 1000000000, 1000000000000, 1000000000000000, 1000000000000000000)); Var i: Integer; F: TSTSFormat; Begin If Size >= 0 Then Begin If SFormat < stsFull Then Begin i := 0; While (i < High(D[False])) and (Size >= D[SFormat >= sts10, i]) do Inc(i); Inc(i, 2); F := SFormat; If F < sts2 Then Inc(F, 4); Result := Format(S[F, i div 3], [2 - (i mod 3), Size / X[SFormat >= sts10, i div 3]]); End Else Result := Format(S[sts2Long, 0], [0, Size / 1]); End Else Result := Format(ErrorStr, [Size, Size / 1]); End; (dieses funktioniert aber nur richtig, wenn der Standardrundungsmodus verwendet wird und bei den 1000er-Schritten muß ich mal sehn, ob es so auch noch stimmt) Für ErrorStr kann man sonstewas angeben, welches genutzt wird, wenn der Wert negativ ist. z.B.: "Fehler", "%d" oder "%1:.0f Byte" |
Re: Grössenangabe automatische Umwandlung
Moin himitsu,
bekomme Fehlermeldung in der Zeile Zitat:
Fehlt da was? Gruß Wolfgang |
Re: Grössenangabe automatische Umwandlung
Auskommentieren. Die Eigenschaft gibt es erst bei neueren Delphi Versionen.
|
Re: Grössenangabe automatische Umwandlung
Danke Michael, funzt :)
[/Edit] Falsches Forum, himitsus Beitrag gehört in die CodeLib [/Edit] |
Re: Grössenangabe automatische Umwandlung
Zitat:
doch für die 3 Ausgaben ist die optimierte Version nicht notwendig :) Da fällt die Zeiterspartnis leider gar nicht in die Wagschale... Dennoch herzlichen Dank, vielleicht hilfts jemanden anderen welcher mehr Konvertierungen benötigt Schöne Grüße Euer GreenHorn |
Re: Grössenangabe automatische Umwandlung
Dein Titel könnte besser heissen:
"Einheiten für Speichermengen" o.ä. |
Re: Grössenangabe automatische Umwandlung
Haben wir nicht schon so einen Beitrag in der Code-Lib? Wenn nicht, wäre es ein Kandidat.
|
Re: Grössenangabe automatische Umwandlung
[OT]
Meinst du? Letztendlich ist das doch nichts besonderes was man nicht selbst hinnbekommen würde oder? Ich habe die Befürchtung, dass wir irgendwann alles in die Codelib aufnehmen. Zum Beispiel Zeichnen eines Vierecks auf einer Canvas, Einfärben einer Canvas etc. Natürlich ist das alles ganz hübsch und wird des öfteren verwendet. Aber je mehr in die Codelib kommt was man mit etwas denken auch schnell selbst zusammen getippt bekommt, destso schwieriger lässt sich das wirklich Interessante finden. Und beim aktuellem Thema habe ich das Gefühl das es wegen des Quelltextes für die Codelib vorgeschlagen wird und nicht wegen dem was man damit erreicht. (und die Codelib soll doch sicher nicht als Sammlung hübscher Quelltexte dienen sondern als Sammlung von Quelltexten mit denen man nützliche Sachen erreicht welche nicht Jederman in 2 Minuten selbst zusammentippt) |
Re: Grössenangabe automatische Umwandlung
Zitat:
Zumindest die Funktion "SizeToString", die man mit Copy & Paste direkt verwenden kann. Natürlich sollte nicht jedes kleine Code-Schnippsel in die CL, speziell dann nicht, wenn ihn kaum einer braucht. Aber gut, die Diskussion können wir auch wo anders führen. ;) |
Re: Grössenangabe automatische Umwandlung
Zitat:
und durch solche Threads wie hier sind da schon ein paar Tage an Arbeit/Bedenkzeit draufgegangen. Weißt du, was das für eine Fizelarbeit war, um das Rundungsverhalten so hinzubekommen, daß genau an den Stellen umschalten zu lassen, wo es auf 4 Dezimalstellen umschalten würde, so daß immer die maximalste Genauigkeit sichtbar ist, welches man mit einem minimalen Platzbedarf von 3 Dezimalstellen hinbekommt? Dieses Rundungsverhalten im Format ist nicht grade überschaubar, darum sind es ja auch so komische/krumme Werte. :wall: [info] blöd wäre es allerdings, wenn jemand am Rundungsverhalten der FPU rumspielt, da diese Werte nur auf das Standardverhalten zugeschnitten sind. |
Re: Grössenangabe automatische Umwandlung
Das geht doch dann bis Peta- oder Exabyte oder?
|
Re: Grössenangabe automatische Umwandlung
Int 64 kommt bis auf 19 (unsigned = 20) Dezimalstellen, also bis Exabyte.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz