Autor |
Beitrag |
tommie-lie
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Sa 23.11.02 17:37
Hallo,
Ich will mehrere Dateien in einer zusammenfassen.
Dazu lese ich alle Dateien ein und speichere sie in einen Stream.
Um jetzt aus dieser einen Datei die alten wiederherstellen zu können, brauche ich ja Start- und End-Byte und den Dateinamen (Datum und Zeit ggf auch).
Diese Daten kann man in einer Extra-Datei abspeichern, wo man sie dann ausliest. Das will ich aber nicht. Ich will diese Informationen auch in dieser einen Datei haben.
Leider habe ich keine Ahnung, wie ich das realisieren kann.
Für meine Idee (immer drei Zeilen: Name, Start, Ende) müsste man wissen, wo die LineFeeds sind und jedesmal nur diese eine Zeile lesen. Das geht aber mit 'nem Stream nicht, also müsste ich erstmal die ersten paarhundert Bytes einlesen und für jedes Byte gucken, ob's ein CR oder LF ist und dann alle vorangehenden als eine Zeile betrachten. Je nach Anzahl der archivierten Dateien, können das aber mehrere Kilobyte sein und ich weiß ja nie genau, wann und wo der "Einleitungsteil" mit den Dateiinformationen zu Ende ist, und wo der "Hauptteil" mit den eigentlichen Dateien anfängt.
Hat da irgendwer irgendwelche Ideen?
Ach ja, ich kann im Stream, aus dem ich lese, nur vorwärts suchen oder ganz an den Anfang springen. Ich kann nicht mit Seek eine Position vor der aktuellen Position angeben!
Tschüß
Thomas
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Sa 23.11.02 20:59
Hallo tommie-lie!
Dein Problem lässt sich relativ einfach lösen! Zunächst schreibst du in die Datei die Länge der Datei und danach schreibst du die ganze Datei rein. Dann wieder die größe von der nächsten Datei und der Inhalt und so weiter. Das ganze dann weiderholen, bis der Stream durchgelesen ist!
Verstanden? Wenn nicht, sag bescheid!
Gruß wulfskin!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
tommie-lie 
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Sa 23.11.02 21:30
das ist mir klar.
Habe ich doch auch geschrieben!
Das PRoblem ist nur das auslesen. Wie kriege ich die Zahl raus, die dann am Anfang jedes Blocks steht? Immerhin ist doch mal eine Datei 10 Byte groß, und mal wieder 10 000 000 Byte. Die Zahlen sind also alle unterschiedlich lang. Genauso wie die Namen. Jeder Dateiname hat eine andere Länge, da ja auch die Verzeichnispfade mitgespeichert werden sollen.
Hätte ich Funktionen, die eine Zeile einlesen, könnte ich ja einfach das Ganze so lösen:
Quelltext 1: 2: 3: 4:
| Start Ende Name {dateiinhalt...ganz lang...} |
Dann lese ich einfach die ersten drei Zeilen aus und weiß, daß in der ersten Zeile die Startbytes liegen, in der zweiten die endbytes und in der dritten der Dateiname.
Aber die Funktionen habe ich in einem Stream nicht.
Und jedesmal nur ein byte zu lesen und zu prüfen, ob das nun zu einem Linefeed gehört, ist doch sicherlich extrem langsam, zumal ja auch in den Dateien, die im Stream sind, Linefeeds drin sein könnten und somit die Routine durcheinanderbringen könnten...
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Popov
Gast
Erhaltene Danke: 1
|
Verfasst: Sa 23.11.02 21:47
Egal ob drei oder zehn oder tausend Byte lang die Datei ist, die länge der Datei mußt du als 4Byte Wert speichern. Also Zuerst 4 Byte mit der länge der Datei, dann die Datei, die nächsten 4 Byte sind wieder die Länge der nächsten Datei, dann die Datei, usw.
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: Sa 23.11.02 23:41
...genau und wenn du ein String mit Variabler Länge speichern möchtest, dann speicher zuerst die Länge und dann den String!
Gruß wulfskin!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
tommie-lie 
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 24.11.02 12:08
also praktisch bei 'ner 10 vorne soviele nullen dranschreiben, daß es 4 byte werden?
Gut, so kann ich's machen, aber wie ist das mit dem Strings gemeint?
Die Länge des Strings schreiben, oder wie?
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
DeCodeGuru
      
Beiträge: 1333
Erhaltene Danke: 1
Arch Linux
Eclipse
|
Verfasst: So 24.11.02 12:39
Zitat: | also praktisch bei 'ner 10 vorne soviele nullen dranschreiben, daß es 4 byte werden? |
Ne, du liest die Größe der Daten in eine (zum Beispiel) Cardinal-Variable ein, die 4 Byte groß ist. Damit kannst du schon mal längen von 4.294.967.295 speichern (knapp 4 GB  Dann schreibst du einfach die Variable vor die Daten und schwups haste deine 4 Byte.
_________________ Viele Grüße
Jakob
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: So 24.11.02 12:46
Hallo tommie-lie!
Zahlen werden immer mit einer konstanten Größe von 1, 2, ...Byte gespeichert, deshalb musst du einfach nur für ein Zahlen-Typ entscheiden, der eine genügen große Zahl speichern kann. So, damit das klar wird, hier mal ein Beispiel, wie du die Dateien speichern könntest. Quelltext 1: 2: 3: 4: 5:
| Aufbau: Länge von Dateiname Dateiname Länge von Datei Datei | 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:
| procedure WriteString(var FileStream: TFileStream; const S: String); var Len: Word; begin Len := Length(S); with FileStream do begin Write(Len, SizeOf(Len)); //Schreibt die Länge des Strings Write(PChar(S)^, Len); //und danach den String selber end; end; const Dateiname = 'C:\test.exe'; var FileStream, ExtFile: TFileStream; L: LongInt; begin FileStream := TFileStream.Create('wasweisich.dat', fmCreate or fmShareExclusive); with FileStream do begin try ExtFile := TFileStream.Create(Dateiname, fmOpenRead or fmShareDenyWrite); //externe Datei öffnen try WriteString(FileStream, ExtractFileName(Dateiname)); //Dateiname speichern L := ExtFile.Size; Write(L, SizeOf(LongInt)); //Größe der Datei speichern Write(ExtFile, SizeOf(ExtFile)); //Datei speichern finally ExtFile.Free; end; finally Free; end; end; end; | Ich hoffe das Beispiel klappt, wenn nicht, schreib einfach nochmal!
Gruß wulfskin!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
Popov
Gast
Erhaltene Danke: 1
|
Verfasst: So 24.11.02 12:56
tommie-lie hat folgendes geschrieben: | also praktisch bei 'ner 10 vorne soviele nullen dranschreiben, daß es 4 byte werden? |
Nicht ganz. Davorschreiben, NICHT drannschreiben. Ein normaller Integer ist doch momentan 32Bit bzw. 4Byte lang. Das kannst du messen mit:
Quelltext 1: 2: 3: 4: 5: 6:
| procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin ShowMessage(IntToStr( SizeOf(i) )); end; |
Der hat schon seine Nullen davor. Du mußt nur den ganzen Integer abspeichern.
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| procedure TForm1.Button1Click(Sender: TObject); var s: String; i: Integer; begin s := '0123456789'; i := Length(s); ShowMessage( IntToStr(i) ); ShowMessage( IntToStr(SizeOf(i)) ); end; |
Du muß nur die einzelnen Bytes auslesen:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| procedure TForm1.Button1Click(Sender: TObject); var s: String; i: Integer; b4, b3, b2, b1: Byte; begin s := '0123456789'; i := Length(s); ShowMessage( IntToStr(i) ); ShowMessage( IntToStr(SizeOf(i)) );
b1 := Byte(i shr 0); b2 := Byte(i shr 8); b3 := Byte(i shr 16); b4 := Byte(i shr 24); end; |
Die ersten vier zeichen des Strings sind die Länge:
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| procedure TForm1.Button1Click(Sender: TObject); var s: String; i: Integer; b4, b3, b2, b1: Byte; begin s := '0123456789'; i := Length(s); ShowMessage( IntToStr(i) ); ShowMessage( IntToStr(SizeOf(i)) );
b1 := Byte(i shr 0); b2 := Byte(i shr 8); b3 := Byte(i shr 16); b4 := Byte(i shr 24);
s := Chr(b4) + Chr(b3) + Chr(b2) + Chr(b1) + s; end; |
Jetzt nur noch weiterdenken:
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:
| procedure TForm1.Button1Click(Sender: TObject); var s, s2: String; i: Integer; b4, b3, b2, b1: Byte; begin s := '0123456789'; i := Length(s); ShowMessage( 'Länge s = ' + IntToStr(i) ); ShowMessage( 'Bytes i = ' + IntToStr(SizeOf(i)) );
b1 := Byte(i shr 0); b2 := Byte(i shr 8); b3 := Byte(i shr 16); b4 := Byte(i shr 24);
s := Chr(b4) + Chr(b3) + Chr(b2) + Chr(b1) + s; s := s + 'Nur für den Test';
i := 0; //Nur für den Test
i := b4 shl 24; i := b3 shl 16; i := b2 shl 8; i := b1 shl 0;
Delete(s, 1, SizeOf(i));
s2 := Copy(s, 1, i); Delete(s, 1, i);
ShowMessage( 'Text s = ' + s2 ); end; |
|
|
Popov
Gast
Erhaltene Danke: 1
|
Verfasst: So 24.11.02 13:07
|
|
tommie-lie 
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 24.11.02 13:46
Das mit dem Integers ist mir klar.
Ich habe nur ein LongWord genommen, weil man ja keine negativen Zahlen braucht und ich so 4 GB in einen Stream kriege (macht zwar das FAT-Dateisystem nicht mit, aber wer weiß, unter Linux...).
Das Codebeispiel hättest du mir gar nicht schicken brauchen. Während deinem Post habe ich nämlich schon fleißig gearbeitet und es geschafft, zwei Dateien längenabhängig in einen Stream zu kriegenb. Meine Frage war ja nur noch, wie ich den Dateinamen speichern kann.
Das Speichern der länge des Namens, dann den Namen, dann die Länge der Datei und dann erst die Datei ist zwar extrem aufwändig, vor allem wenn ich noch ein erstellungsdatum brauche, aber es scheint wohl wirklich die einzige Möglichkeit zu sein.
Dein Codebeispiel habe ich zwar nicht aktiv ausprobiert, aber es scheint als ob es laufen würde, wenn ich's machen würde, wenn ich es noch ein bisschen anpasse (ich speichere nämlich in einen codierten Stream, also einen Stream im Stream, daher kann ich auch nicht rückwärts suchen usw).
@CodeGuru: Jep. Nachdem ich das ausprobiert habe, wollte ich zuerst die Länge als string schreiben, aber dann ist mir ganz schnell aufgefallen, daß ich dann ja immer noch das PRoblem habe *g*. Jetz' mach ich's so, wie du gesagt hast, sogar schon bevor ich deinen Post gelesen habe 
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
tommie-lie 
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 24.11.02 13:57
@popov:
Ich habe meinen letzten Text offline geschrieben, daher habe ich deinen Text vorher nicht gelesen:
Was bringt mir der? Ds Problem, daß ich nicht weiß, wo genau in der Datei der String aufhärt und die Datei anfängt, bleibt doch immer noch bestehen. Ich müsste immer noch erst die länge des gesamtstrings speichern und dann den String. Es wäre also relativ egal, wie ich es mache, weil ich so oder so die gleiche Anzahl an bytes speichern muss: Einmal die Länge des Dateinamens, einmal der Dateiname selber und einmal die Länge der Datei. Ob jetzt die Länge der Datei als einzelne Bytes im String liegen,. oder als LondWord direkt in die Datei geschrieben werden, ist doch egal.
Aber ich wüsste was anderes:
Ich sammele alle Dateinamen als mit Semikoli getrennte Strings, die dann gefolgt von der Dateilänge eine Ansammlung von Dateiinformationen ergeben:
Quelltext 1:
| Dateiname1; Länge1; Dateiname2; Länge2; Dateiname3; Länge3; ... |
Jetzt schreibe ich vorne an die Datei nur noch die Länge dieses gesamtstrings. Dann kann ich die ersten paar Bytes auslesen, die die Dateiinformationen enthalten, und weiß, das anschließend alle Dateien folgen. Die Dateiinfromationen kan ich dann in einem Array speichern und kann so bequem auf alle einzelnen Dateien im Stream zugreifen.
Wäre doch besser, oda?
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: So 24.11.02 14:27
Wie wär´s mit einer Erinnerung an vergangene Tage:
DOOM!
Bei dem Spiel (und anderen) lag eine WAD-Datei bei. Diese enthielt unkomprimiert alle Ressourcen des Spiels. Den Anfang bildete ein 12 Bytes großer Header mit der ID "IWAD" (4B), dann folgten Anzahl der Ressourcen (4B) und Offset des internen Verzeichnisses (4B).
Das interne Verzeichnis enthielt den Dateinamen (8 Bytes im Original, glaube ich; 12 Bytes beim WAD2-Format), gefolgt von Größe (4B) und Offset (4B).
Was war zu tun?
- Header auslesen, auf Gültigkeit prüfen, Anzahl der Ressourcen merken
- Verzeichnis anspringen und in einer Schleife jede einzelne Ressource auslesen ->
- Ressourcennamen merken, Offset anspringen und x Bytes (Größe) lesen ... und irgendwas damit machen
Damit enthielt die WAD/WAD2-Datei alles, was erforderlich war. Und auf der Grundlage entstand mein WadExtractor, der die Sprites usw. anzeigte und generell das Extrahieren der Ressourcen erlaubte.
Kannst du das verwenden?
btw:
Zitat: | Einmal die Länge des Dateinamens, einmal der Dateiname selber ... |
Wenn du einen String benutzt, befindet sich die Länge bereits im Zeichen Null. Aber ich tendiere eher zur WAD-Methodik, nämlich: alle benutzen die gleiche feste Länge. Dann könntest du zum Auslesen z.B. ein Record verwenden, das Name, Größe und Offset innerhalb der Datei enthält.
Und ja: früher habe ich das mit BlockRead gemacht. Streams gab´s da noch nicht ... Die Idee müsste also angepasst werden, willst du Streams nutzen.
|
|
tommie-lie 
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: So 24.11.02 15:54
MathiasSimmack hat folgendes geschrieben: | Kannst du das verwenden? |
Jein.
Es bringt mich nicht weiter, weil die Dateinamen nach deinen Angaben 8 Bytes lang sind, bzw 12 Bytes. Fazit: Dateiname ist maximal 8 Bytes lang.
Selbst FAT12 kann schon Dateinamen, die 8 Bytes lang sind und zusätzlich noch eine Extension enthalten. Außerdem brauche ich noch den Pfad, der ja wieder länger als 8 Zeichen lang ist.
Aber das System ist klar. Ich brauche zwar keine Header, weil das sowieso gültig ist. Wenn man an der enddatei irgendwas dran ändert, ist das ganze Ding im Eimer, also entweder funktioniert die Datei, oder sie ist sowieso nicht mehr lesbar.
Aber das ich die Größe der Dateien merken muss, war mir von vornherein klar. Nur ben der Dateiname und evtl das Änderungsdatum der Datei macht probleme. Und zwar eben weil die Strings alle unterschiedlich lang sind und ich somit nicht einfach sgaen kann "Lies mir 11 Byte und ich habe Dateinamen + Extension", sondern ich muss mir vorher überlegen, wie ich festhalten kann, wie lang der Dateiname ist.
Mit Streams muss ich arbeiten, wegen der Codierung.
Speichert er denn, wenn ich per Write einen String in den Stream schreibe, auch das nulte Zeichen rein? Dann wäre es nämlich schön einfach. Dann kann ich alle Strings plus die Dateilänge hintereinander reinschreiben. Dann lese ich das erste Byte, habe die Länge des Strings, lese diesen, lege diese Datei an, lese die darauffolgenden 4 Byte als Länge der Datei, lese die Datei, und schließe die Zieldatei weider. Dann wieder von vorne, bei der nächsten Datei im Quell-Stream angelangt: Wieder die länge des Strings lesen usw.
Eigentlich dürfte er doch gar nicht das 0te Zeichen mitlesen, weil er doch nur die Zeichen als Character reinschreibt?
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
wulfskin
      
Beiträge: 1349
Erhaltene Danke: 1
Win XP
D5 Pers (SSL), D2005 Pro, C, C#
|
Verfasst: So 24.11.02 19:06
tommie-lie hat folgendes geschrieben: | Speichert er denn, wenn ich per Write einen String in den Stream schreibe, auch das nulte Zeichen rein? |
Ich glaube nicht, probier es einfach aus! Oben habe ich dir ja gezeigt, wie du es machen kannst! Was passt dir daran nicht?
Gruß wulfskin!
_________________ Manche antworten um ihren Beitragszähler zu erhöhen, andere um zu Helfen.
|
|
Popov
Gast
Erhaltene Danke: 1
|
Verfasst: So 24.11.02 22:42
Manchmal hab ich das Gefühl, daß es hier so vor sich geht:
> Mist, mein Auto ist kaput. Kann mit einer ein Tip geben wie ich jetzt in die Stadt komme?
- Nim doch den Bus.
> Mit dem Tip kann ich nichts anfangen. Bei uns fahren keine Busse in die Stadt, nur Zuge. Hat noch einer ein Tip?
Zitat: | Ich habe meinen letzten Text offline geschrieben, daher habe ich deinen Text vorher nicht gelesen:
Was bringt mir der? Ds Problem, daß ich nicht weiß, wo genau in der Datei der String aufhärt und die Datei anfängt, bleibt doch immer noch bestehen. Ich müsste immer noch erst die länge des gesamtstrings speichern und dann den String. Es wäre also relativ egal, wie ich es mache, weil ich so oder so die gleiche Anzahl an bytes speichern muss: Einmal die Länge des Dateinamens, einmal der Dateiname selber und einmal die Länge der Datei. Ob jetzt die Länge der Datei als einzelne Bytes im String liegen,. oder als LondWord direkt in die Datei geschrieben werden, ist doch egal. |
Wenn das alles klar ist und alles egal ist, warum fragst du dann? Wo ist das Problem das ganze in die Praxis umzusetzen?
Wenn es eben nicht das
Quelltext 1:
| Dateiname1; Länge1; Dateiname2; Länge2; Dateiname3; Länge3; ... |
dann das
Quelltext 1:
| #Stringlänge, Dateinamenstring, Integerdatum, Integerbyte, Dateilänge, Dateistring, #Stringlänge, Dateinamenstring, Integerdatum, Integerbyte, Dateilänge, Dateistring, #Stringlänge, Dateinamenstring, Integerdatum, Integerbyte, Dateilänge, Dateistring, #Stringlänge, Dateinamenstring, Integerdatum, Integerbyte, Dateilänge, Dateistring, #Stringlänge, Dateinamenstring, Integerdatum, Integerbyte, Dateilänge, Dateistring... |
Wenn du ein festen Wert hast, dann brauchst du nirgendwo auzuschreiben wie lang der ist. Wenn du aber eine variable Länge hast, dann muß du die irgendwo vorher notieren.
Wenn du dur ein String vom maximal 256 Zeichen hast, dann brauchst du keinen 4 Byte Wert, sondern nur ein Byte Wert. Wenn du auf jeden Fall 256 Zeichen speicherst, egal ob er nun 10, 20 oder 100 Zeichen lang ist, dann brauchst du überhaubt keine Zahl. Du kannst auch mit einem #0 den String abschleßen. Dann ist es egal wie lange der DateinamenString ist. Dann kannst du die speichern wie du willst, muß aber später von "hand" abzählen. Alles hat seine Vor und Nachteile.
Vor dir kammen schon andere auf die Idee sowas zu machen und kammen auch auf die Lösungen. Feste Längen - Datenbanken, variable Längen - vorher die Länge notieren und irgendwo speichern.
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 25.11.02 09:28
Zustimmung, Popov.
Lösungsansätze gibt´s nun genug. Würde man die erst mal ausprobieren und hinterher sagen: "das geht aus dem und dem Grund nicht" oder "hey, das klappt prima", dann wäre das Thema möglicherweise schon beendet.
|
|
tommie-lie 
      
Beiträge: 4373
Ubuntu 7.10 "Gutsy Gibbon"
|
Verfasst: Mo 25.11.02 16:48
Irgendwie reden wir aneinander vorbei...
Ich will einfach eine möglicsht kompakte, aber schnelle Lösung.
Also nochmal zur Erklärung meiner Posts, für alle die länger brauchen:
Von Anfang an war mir klar, daß ich die Länge der Datei, die gespeichert werden soll, reinschreiben muss. Aber ich brauche auch den String des Dateinamens.
Dann haben mir einige geholfen und gesagt, daß ich festhalten muss, wie lang der String ist.
Bis dahin war ja noch alles okay.
Dann hat Popov den langen Post geschrieben, mit dem ich absolut nicht klar kam. Was sollte damit gelöst worden sein? Ich muss nach wie vor mitspeichern, wie lang der String ist, der die Dateinamen enthält, nur daß dieser nun ein komma-getrennter String ist, denn ich wieder in eine StringList eintragen kann. Das Problem, daß ich einmal die Länge des Strings und einmal die Länge der Datei speichern muss, bleibt bestehen.
Okay, erstes Missverständnis. Dann hat Mathias was von WAD erzählt. Das war noch verwirrender. Jetzt muss ich nicht nur notieren, wie lang mein String ist, wie er heißt, und wie lang die Datei ist, nein jetzt muss ich auch noch den Anfang des Verzeichnisses notieren und einen Header auf gültigkeit prüfen.
Das einzige, was ich gebrauchen konnte war, daß bei einem string im Zeichen 0 die Länge steht. Daran habe ich vorher wirklich noch nicht gedacht und das ist das einzige, wofür ich mich schuldig bekenne. Aber mittlerweile ist mir aufgefallen, daß die Dateinamen ja auch länger als 255 Zeichen sien können (zumindest theoretisch) und somit auch nicht immer ShortStrings sind, wodurch sich der Vorteil der Länge im 0ten Byte wieder verflüchtigt, als plädiere ich unschuldig im Sinne der Anklage (das ist mir gestern übrigens noch nicht aufgefallen, also dachte ich gestern tatsächlich noch, daß ich im 0ten Byte eines Strings die Länge vorfinde).
Mit dem Absatz, den Popov zitiert hat (mit dem egal), meinte ich nur, daß es egal ist, wo die Länge liegt, als Zeichen (0, 1, 2, ...) im String, oder als binär gepsiecherter LongWord in der resultierenden Datei. Klar, wie ich das am geschicktesten speichere, war es mir zu dem Zeitpunkt nicht.
Das benutzen von markanten Zeichen, zum Beipsiel #0 und das nachfolgende überprüfen jeden Zeichens auf seine terminierende Wirkung finde ich für zu aufwändig und für zu langsam, als das einfache mitspeichern der Länge.
Da es also nichts besseres gibt, und ich keine andere Lösung finden kann, werde ich es wohl so machen müssen:
DateinamenLänge: LongWord
Dateiname: String
Datum: irgendeine Zahl (weiß jetzt nicht im Kopf, was ich da nehmen kann)
Zeit: siehe letzter Eintrag
Dateilänge: LongWord
Datei: einfach aus der Quelldatei lesen
So und nicht anders ist das einzige, was in diesem Topic sinnvolles rauskam, weil ein Inhaltsverzeichnis (wie bei WAD) noch mehr verwaltungsaufwand wäre und die Datei noch größer machen würde, und bisher keine andere Möglichkeit geschildert wurde, die Länge eines Strings festzuhalten, ohne irgendwelche Extra-Anstalten zu machen.
_________________ Your computer is designed to become slower and more unreliable over time, so you have to upgrade. But if you'd like some false hope, I can tell you how to defragment your disk. - Dilbert
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mo 25.11.02 17:04
Hi!
Hier zwei Prozeduren, die dir die Arbeit mit den Strings abnehmen.
Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19:
| procedure SaveStrToStream(const Stream: TStream; const Value: String); //Schreibt einen dynamischen String in einen Stream var Len: Word; begin Len := Length(Value); Stream.WriteBuffer(Len, SizeOf(Len)); if Len > 0 then Stream.WriteBuffer(Pointer(Value)^, Len); end;
procedure LoadStrFromStream(const Stream: TStream; var Str: String); //Liest einen dynamischen String aus einem Stream var Len: Word; begin Stream.ReadBuffer(Len, SizeOf(Len)); SetLength(Str, Len); if Len > 0 then Stream.ReadBuffer(Pointer(Str)^, Len); end; |
Cu,
Udontknow
|
|
MathiasSimmack
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 25.11.02 17:06
Der einzige, der etwas länger braucht, scheinst du zu sein. Weder Popov noch ich haben gesagt was du tun musst. Wir wollten dir zeigen, was du tun kannst.
Du suchst nach einer Lösung, und wir haben dir mehrere geboten. Wer sagte, dass du dich sklavisch nach irgendwelchen Vorgaben richten musst? Kein Mensch!
Speziell das WAD-Format war nur die Beschreibung einer Lösung, die ich selbst bereits erfolgreich -in abgewandelter Form!- für meinen alten DOS-Installer benutzt habe.
|
|
Dieses Thema ist gesperrt, Du kannst keine Beiträge editieren oder beantworten.
Das Thema wurde von einem Team-Mitglied geschlossen. Wenn du mit der Schließung des Themas nicht einverstanden bist, kontaktiere bitte das Team.
|
|