![]() |
Delphi-Version: 5
FormatFileSize
Hallo, habe hier (Beitrag finde ich irgendwie nicht mehr) diese Funktion entdeckt.
Code:
Die wollte ich gerne nutzen, habe aber auch irgendwo gelesen, dass man "Extended" gar nicht nehmen sollte, sondern "Int64". Ob das nun allg. gemeint war oder speziell... kein Plan. Wollte es nur mal erwähnen, da hier in der Funktion ja "Extended" genommen wird. Die Funktion geht jedenfalls aber wollte hier noch eine kleine Änderung vornehmen, nämlich das nach dem Komma keine Nullen angezeigt werden.
function FormatFileSize(const AFileSize: Int64; Use1024: Boolean = True): String;
const Sizes1024: array[0..8] of string = ('Bytes', 'KiB','MiB','GiB','TiB','PiB','EiB','ZiB','YiB'); Sizes1000: array[0..8] of string = ('Bytes', 'KB','MB','GB','TB','PB','EB','ZB','YB'); var _size: Extended; _Unit: integer; s: string; Divisor: Integer; begin try if (Use1024) then Divisor := 1024 else Divisor := 1000; _size := AFileSize; _Unit := Low(Sizes1024); while (_size >= Divisor) and (_Unit < High(Sizes1024)) do begin _size := _size / Divisor; Inc(_Unit); end; if (Use1024) then s := Sizes1024[_Unit] else s := Sizes1000[_Unit]; Result := Format('%.2f %s', [_size, s]); except Result := 'ERR'; end; end; Beispiele: 1,59 = 1,59 1,50 = 1,5 1,02 = 1,02 1,00 = 1 Auch würde ich gerne das Komma durch ein anderes Zeichen ersetzen können (z.B. ein Punkt). Beides kann man natürlich außerhalb der Funktion im nachhinein noch machen aber das wäre wohl nicht die beste Lösung. Auch würde ich gerne mal wissen, wer Dateien hat, die so ab TerraByte anfangen. Alles war danach kommt, kann ich mir dann gar nicht mehr vorstellen... also als einzelne Datei :) Vielleicht die NASA mit Daten in ner ZIP-Datei von 422 Exabyte? *lach Michael |
AW: FormatFileSize
Für die Stelligkeit kannst Du
Zitat:
Delphi-Quellcode:
ändern. Für das Dezimal- bzw. Tausendertrennzeichen könntest Du einen weiteren Parameter definieren. Dann musst Du aber innerhalb der Funktion entsprechende TFormatSettings deklarieren und diese in der Überladung der Format-Funktion mit übergeben.
Result := Format('%f %s', [_size, s]);
[edit] Ich sehe gerade: Delphi 5, stimmt das? Falls ja, klappt das nicht so wie beschrieben, dann müsstest Du die globale Variable Decimalseparator manipulieren, aber bitte vorher Wert sichern und zum Schluss wiederherstellen. [/edit] |
AW: FormatFileSize
Danke für deine Hilfe aber ".2" wegzulassen, geht nicht. Ich glaub ".2" ist sowieso Standard, wenn man es nicht angibt.
Ich habe die Zeile mit dem Format eben mal so geändert/erweitert:
Code:
So komme ich zu meinem Ziel aber ist hier wohl keine gute Lösung. Mit dieser Idee könnt ich auch leicht das Komma in ein anderes Zeichen austauschen.
Result := Format('%.2f', [_size]);
if Result[Length(Result)]='0' then result := Copy(Result,0,Length(Result)-1); if Result[Length(Result)]='0' then result := Copy(Result,0,Length(Result)-1); if Result[Length(Result)]=',' then result := Copy(Result,0,Length(Result)-1); Result := Result + ' '+s; Nutze Delphi 10 (die neue Community-Version). Das da Delphi 5 steht, ist mir nie aufgefallen. Das hat das Forum wohl als Standard gesetzt, als ich mich hier registriert habe. Ändere ich gleich mal. Edit: Mit der Version... das war bei der Thread-Erstellung. Da gibt es auch ein Eingabefeld dazu. Dort steht 5 als Standard :) Michael |
AW: FormatFileSize
Wer rundet jetzt falsch? Windows oder die Funktion?
Eine Datei mit 1148928 Bytes 1148928 / 1024 / 1024 = 1,0957031 Also eigentlich aufrunden. Das macht die Funktion. Also sie gibt 1,1 MiB zurück. Windows 10 spuckt aber 1.09 raus (mit der Angabe MB. So wie ich das verstanden habe sollte ja hier dann "MiB" stehen) Alles mal wieder durcheinander :) Michael |
AW: FormatFileSize
Mit Format geht das wohl nicht, wohl aber mit FormatFloat:
Delphi-Quellcode:
result := Format('%s %s' [FormatFloat('0.##', _size, TFormatSettings.Invariant), s]);
|
AW: FormatFileSize
Zitat:
Und Format rundet ja den Wert auf. Wie ich oben geschrieben habe, macht Windows wieder ne andere Rundung. Jeder kocht irgendwie sein eigenes Süppchen, sprich ich brauch wieder 2 Versionen, damit der Benutzer entscheiden kann. Den Befehl "Format" dazu bewegen, abzurunden... das ist bestimmt auch eine "TFormatSettings" Einstellung? Michael |
AW: FormatFileSize
Zitat:
1148928 Bytes sind ungerundet 1,09 MiB. Gerundet 1,1 MiB. |
AW: FormatFileSize
Ich hab jetzt:
Code:
.free brauch ich ja hier nicht (verwirrt mich immer). So habe ich den "Punkt" und wenn ich ein Komma haben möchte mach ich dann natürlich "fs.DecimalSeparator := ',';".
fs := TFormatSettings.Create;
fs.DecimalSeparator := '.'; result := Format('%s %s', [FormatFloat('0.##', _size, fs), s]); Je nach dem wo der Code steht, muss man noch "Application.UpdateFormatSettings := false;" setzen, da sonst bei "WM_WININICHANGE" oder "RM_TaskbarCreated" die FormatSettings wieder überschrieben werden (hier im Forum in einem Thread gelesen). Nur mal so als Info. Jetzt fragt sich nur noch wie ich dem "Format" beibringen kann, ob er auf/abrunden soll. Es wird ja aufgerundet. Zitat:
Michael P.s. Der Total-Commander gibt beispielsweise "1,0 M" zurück. Jeder macht's anders. Da weiß man gar nicht, welcher Weg der richtige ist. |
AW: FormatFileSize
Ich denke am besten ist es, wenn man nicht rundet und nach der, sagen wir mal zweiten Stelle, alles abschneidet.
Ich gucke da gerne auf Linux. Die zeigen MB (nicht MiB) richtig an. Die nehmen das also etwas ernster. Hier mal ein Beispiel. ![]() Da kann man Testdateien runterladen. Die 5 MB große Datei sind in Wirklichkeit 5,2 MB. Was Windows falsch anzeigt, übernehmen also auch Webseitenbetreiber blind. Daher mein Rat, sich das mal unter Linux anzusehen. Dort wird's richtig gemacht. |
AW: FormatFileSize
Verwirrt es dich auch nach dem Duschen den Hahn zu zu drehen und die benutze Wäsche in den Wäschekorb zu werfen?
|
AW: FormatFileSize
Es ist nun einmal Fakt, dass Windows eine falsche Speichergröße anzeigt.
Und nur weil sich jeder blind darauf verlässt, dass Windows es schon richtig macht und somit die Speichermengen MB statt MiB usw übernimmt, gibt es diese Verwirrung. Ich weiß nicht genau welches Problem du hast. Aber du schreist in den Themen selber rum, dass die Leute die aktuell besprochene Thematik einzuhalten haben, schreibst hier aber selber irgendeinen Käse. Aber wie oben erwähnt. Windows zeigt es seit Jahren falsch an, und jeder übernimmt es blind ohne darüber nachzudenken. |
AW: FormatFileSize
Zitat:
|
AW: FormatFileSize
Zitat:
Ja, nur gelesen :) Dachte es wäre wichtig, deshalb wollt ich das hier dazuschreiben. Aber Danke für die Info. Ich habe jetzt folgendes, da man ja nicht aufrunden soll.
Code:
Ich schneide jetzt einfach ab auf 2 Stellen nach dem Komma und sollte dann zufällig noch eine "0" am Ende sein (beim ersten Copy z.B. aus 232,20343 = 232,20) wird diese "0" dann auch mit dem zweiten Copy entfernt. Beim ersten Copy "kp+2" gibt's keine Probleme wenn der Wert z.B. "232,2" beträgt. Da nimmt er wohl nur +1 weil es mehr nicht gibt. Am Ende füge ich dann noch die Bezeichnung ein "KB, KiB etc."
fs := TFormatSettings.Create;
fs.DecimalSeparator := ','; _size := 23.203; result := floattostr(_size); kp := Pos(',',result); if kp > 0 then result := copy(result,0,kp+2); if result[length(result)]='0' then result := copy(result,0,length(result)-1); result := result + ' '+s; Edit: Muss doch den 3 Zeiler nehmem, sprich 2x auf 0 prüfen. Der Wert kann ja z.B. auch "232,0034383" sein Also doch so:
Code:
Michael
if Result[Length(Result)]='0' then result := Copy(Result,0,Length(Result)-1);
if Result[Length(Result)]='0' then result := Copy(Result,0,Length(Result)-1); if Result[Length(Result)]=',' then result := Copy(Result,0,Length(Result)-1); |
AW: FormatFileSize
Da dieses Thema ja stark von der Oberlehrerfraktion besetzt ist:
Wenn man einen Wert rundet, dann werden nach Selbigem niemals die Nachkommastellen entfernt.
Code:
Du kannst dir also diesen Zirkus sparen.
232,0034383 auf 2 Nachkommastellen gerundet: 232,00
|
AW: FormatFileSize
Da der Wert auch 0 sein kann... Update:
Ohne "if Result <> '0' Then" würde es nämlich dann bei den Wert "0" ein Fehler verursachen.
Code:
Michael
fs := TFormatSettings.Create;
fs.DecimalSeparator := ','; result := floattostr(_size); kp := Pos(',',result); if kp > 0 then result := copy(result,0,kp+2); if Result <> '0' Then Begin if Result[Length(Result)]='0' then result := Copy(Result,0,Length(Result)-1); if Result[Length(Result)]='0' then result := Copy(Result,0,Length(Result)-1); if Result[Length(Result)]=',' then result := Copy(Result,0,Length(Result)-1); End; result := result + ' '+s; |
AW: FormatFileSize
Zitat:
Michael |
AW: FormatFileSize
Zitat:
![]() |
AW: FormatFileSize
Zitat:
Ich würde das explizit ausprogrammieren:
Delphi-Quellcode:
if <mit Punkt> then begin // sprachinvariant, immer mit Punkt fs := TFormatSettings.Invariant; end else begin // mit Komma oder was im Windows halt gerade eingestellt ist fs := FormatSettings; end; result := Format('%s %s', [FormatFloat('0.##', Floor(100*_size)/100, fs), s]); |
AW: FormatFileSize
Zitat:
|
AW: FormatFileSize
Zitat:
Aber wegen diesen FormatSettings… Wenn ich immer:
Code:
nehme, bin ich auf der sicheren Seite mit meinem Komma oder Punkt. Oder?
fs := TFormatSettings.Create;
fs.DecimalSeparator := ','; // oder '.' oder '/' (wie ich halt will) Michael |
AW: FormatFileSize
Ich meine sowas:
Delphi-Quellcode:
Basierend auf dieser Aussage:
var
_size: Extended; orgMode: TRoundingMode; begin _size := 1.0957031; orgMode := SetRoundMode(rmDown); try Assert(FormatFloat('0.##', _size, TFormatSettings.Invariant) = '1.09', 'Abrunden klappt nicht!'); finally SetRoundMode(orgMode); end; end; Zitat:
Zitat:
|
AW: FormatFileSize
Da ich mich gleich an Strand klatsche hab ich keine Zeit mehr, aber mein Vorschlag beinhaltet Beispiel Code, wenn man nichts rundet, rundet man nichts. Also wo kommt Round() vor?
Falls ich darauf noch Lust haben sollte, schreibe ich was mit Delphi basierend aus dem Informationen vom Link und nicht basierend auf irgendwas was nicht Round() enthält. Man kann Round() auch in Format() reinbringen... |
AW: FormatFileSize
Also SetRoundMode behalte ich mal im Hinterkopf. Danke für die Info.
Find jetzt die Zeile "result := Format('%s %s', [FormatFloat('0.##', Floor(100*_size)/100, fs), s]);" passt ganz gut. KodeZwerg und Uwe Raabe... ich hoffe ihr streitet nicht rum :) Aber Windows macht wirklich sein eigenes Ding. Abgesehen von der Bezeichnung der Dateigrößen... 308736 Bytes / 1024 = 301,5 (Windows gibt 301 aus) <- Datei System32\wusa.exe 14848 Bytes / 1024 = 14,5 (Windows gibt 14,5 aus) <- Datei System32\wshirda.dll Mal mit ",5" mal ohne. (im Explorer Ansicht Modus "Liste" oder bei den Datei-Eigenschaften) Im Modus "Details" (dort ist alles ohne Nachkommastellen) die wusa.exe mit 302 wobei in der Statusleiste dann gleichzeitig 301 steht Ich gebe jetzt z.B. bei der wusa.exe 301,5 KiB aus. Schon komisch Michael |
AW: FormatFileSize
Zitat:
|
AW: FormatFileSize
Zitat:
Hab Euch alle lieb.:thumb: |
AW: FormatFileSize
Windows 10 zeigt im Explorer als Größe den Wert 302 KB und bei den Eigenschaften 301 KB (308 736 Bytes) an.
Konsistent ist da also anders. Im Explorer erfolgt die Berechnung mit dem ![]() ![]() |
AW: FormatFileSize
Zitat:
Ich schrieb ja oben wusa.exe und wshirda.dll (mal mit ,5 mal ohne) im selben Ansichtmodus. (Fette Schrift = Ansicht von Windows in den Eigenschaften) wshirda.dll: Größe = 14848 / 1024 = 14,5 (14,5) Diff. 0 wusa.exe: Größe = 308736 / 1024 = 301,5 (301) Diff. 0,5 Also Windows10 rundet (bei der gleichen Ansicht) bei der wshirda.dll nicht, bei der wusa.exe aber schon. Total Sinnfrei. Aber ich mache mir jetzt da kein Kopf mehr mit diesem Programm aus der Garage (*lach). Ich gebe bei beiden Dateien ",5" mit aus. Michael |
AW: FormatFileSize
Zitat:
Und hier rundet er eben nicht auf x Nachkommastellen, sondern auf 3 "sichtbare" Dezimalstellen. |
AW: FormatFileSize
Zitat:
Nur bei den Bytes sind es mal weniger als 3 Zahlen. Naja, 92 Bytes als 92,0 Bytes anzuzeigen wäre dann etwas peinlich :) Aber vielleicht finde ich ja noch eine 3,25 Bytes Datei *lach Michael |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:00 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 by Thomas Breitkreuz