Seite 1 von 2

Platzerhalter in HTML- oder RTF-Datei ersetzen

Verfasst: 08.04.2019 18:09
von bin_neu_hier
Hallo Leute,

ich möchte Folgendes tun:

Eine Datei (entweder RTF oder HTML, kann beides vorkommen) in einen String einlesen, darin einige Ersetzungen mit Replacestring() vornehmen (vorher eingesetzte Platzhalter, der String wird also an Länge zunehmen, grob gepeilt so um die 10%) und dann wieder je nach Quelldatei als HTML- oder RTF-Datei speichern. Die Platzhalter sehen so aus: @xxx@. xxx ist die Nummer eines Gadgets - einige Platzhalter können in einer Datei auch mehrfach vorkommen.

Wie kann ich sicherstellen, dass die ganze Datei geladen wird (nicht dass zwischendrin ein "Null" den Ladevorgang beendet)? Könnte so ein String auch ein "Null" oder andere Zeichen, deren Ascii-Code für Steuerzwecke verwendet werden, aufnehmen? Könnte sowas überhaupt in HTML- oder RTF-Dateien vorkommen?

Die größte der Dateien ist rund 120 kb groß, kann das ein String noch aufnehmen? Wäre da auch noch "Luft nach oben"?

Mein Projekt wird am Ende nur einen einzigen User haben, die Anzahl der Credits (die Helfer aus diesem Board) ist also schon jetzt um einiges höher!

Edit by NicTheQuick: Titel leichter auffindbar gemacht

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 08.04.2019 19:48
von Sylvia
Hi bin_neu_hier,

vergiss den Kram mit Strings...geht nicht/zu umständlich.

Habe jetzt kein Bock, hier einen fertigen Code hinzulegen, aber ich würde mit AllocateMemory() , OpenFile(), ReadData() die Datein einlesen und mit den Memory-Befehlen arbeiten. Musst halt ein Replace emulieren. Danach wieder mit WriteData() abspeichern. Musst halt immer wissen, wo im Speicher dann die Daten enden nach der Veränderung. Nicht sparen mit AllocateMemory()! Weisst ja vorher nicht, was am Ende rauskommt

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 08.04.2019 19:50
von mk-soft
HTML und RTF Dateien sind im weiten Sinne Textdateien mit Steuerzeichen oder Formatierter Text.
Ein Zeichen NULL (Wert 0) kann (und darf) in einer Textdatei nicht vorkommen, da diese in Verarbeitung von Strings IMMER ein ende ist.

Dann noch die Zeichenformatierung (BOM) beachten. Ascii, UTF8, Unicode, etc

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 08.04.2019 20:06
von mk-soft
Sylvia hat geschrieben:Hi bin_neu_hier,

vergiss den Kram mit Strings...geht nicht/zu umständlich.

Habe jetzt kein Bock, hier einen fertigen Code hinzulegen, aber ich würde mit AllocateMemory() , OpenFile(), ReadData() die Datein einlesen und mit den Memory-Befehlen arbeiten. Musst halt ein Replace emulieren. Danach wieder mit WriteData() abspeichern. Musst halt immer wissen, wo im Speicher dann die Daten enden nach der Veränderung. Nicht sparen mit AllocateMemory()! Weisst ja vorher nicht, was am Ende rauskommt
Sehr hilfreich hier im Anfängerforum...
Natürlich geht es und so umständlich ist es auch wieder nicht, wenn man weis was man ersetzen möchte.

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 09.04.2019 22:19
von bin_neu_hier
Danke Sylvia, bestimmt gut gemeint, aber ... äh ... ich bin noch nicht so weit, den String-Kram vergessen zu können. Werde wahrscheinlich auch nie in der Championsleague der Programmierer landen, da emulier ich mir mal nix vor.

Aber vielleicht kann doch noch jemand helfen. Brauche einen Schubs von Euch in die richtige Richtung. Mit den HTML-Dateien komme ich klar, die werden korrekt geladen, manipuliert und gespeichert, nur bei den RTF-Dateien komme ich nicht weiter. Mein Code-Fragment zeigt die Stelle, an der erkannt wird, dass eine RTF-Datei geladen, manipuliert und gespeichert werden soll.

Code: Alles auswählen

  Case ".rtf"
        flagg = #PB_Ascii    ;damit ich beim ausprobieren nicht zig-mal ändern muss

        err = ReadFile(#loadfilenum, file$, flagg)
        If err <> 0
          
          While Eof(#loadfilenum) = 0
            x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))    
          ;  x$ = x$ + ReadString(#loadfilenum, flagg)
            
          Wend
          CloseFile(#loadfilenum)
          
; jetzt string in x$ mehrfach manipulieren mit Replacestring (zwischen 15 und 33 mal, je nach geladener Datei) 

          err = CreateFile(#savefilenum, dateiname$, flagg)
          If err <> 0
            WriteString(#savefilenum, x$, flagg)
            CloseFile(#savefilenum)
            
          Else
            ;konnte nicht geschrieben werden
          EndIf
                   
        Else
          ;konnte nicht geöffnet werden
        EndIf
        
Wenn mit

Code: Alles auswählen

 x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))    
geladen wird, dauert der Ladevorgang sehr lange, so um die 15 Sekunden für 100 KB. Debug x$ zeigt den Inhalt der RTF-Datei ziemlich genau so wie das in Notepad gezigt wird.

Wenn aber mit

Code: Alles auswählen

 x$ = x$ + ReadString(#loadfilenum, flagg)
geladen wird, dauerts kaum 1 Sekunde, aber Debug zeigt's irgendwie komprimiert an, Zeilenumbrüche wie bei mit Readcharakter geladen fehlen. Muss schon mal was "im Busch sein".

Wer kann mir sagen, wie man eine RTF-Datei richtig und einigermaßen zügig in eine Stringvariable einliest und wie man den String nach diversen Manipulationen wieder als RTF-Datei speichert?

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 09.04.2019 23:05
von Bisonte
probiers mal mit dem Flag : #PB_File_IgnoreEOL

Code: Alles auswählen

Case ".rtf"
  flagg = #PB_Ascii    ;damit ich beim ausprobieren nicht zig-mal ändern muss
  
  err = ReadFile(#loadfilenum, file$, flagg)
  If err <> 0
    
    x$ = ReadString(#loadfilenum, flagg|#PB_File_IgnoreEOL)
    
    CloseFile(#loadfilenum)
    
    ; jetzt string in x$ mehrfach manipulieren mit Replacestring (zwischen 15 und 33 mal, je nach geladener Datei)
    
    err = CreateFile(#savefilenum, dateiname$, flagg)
    If err <> 0
      WriteString(#savefilenum, x$, flagg)
      CloseFile(#savefilenum)
    Else
      ;konnte nicht geschrieben werden
    EndIf
    
  Else
    ;konnte nicht geöffnet werden
  EndIf
P.S.: In Ermangelung einer rtf Datei und eines lauffähigen Codes konnte nicht auf Funktion getestet werden ;)

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 10.04.2019 17:42
von bin_neu_hier
Hallo Bisonte,

ja, das war - wieder einmal - ein guter Tipp von Dir :allright: ! Hast mir schon (mindestens) 2x über die Straße geholfen, herzlichen Dank dafür!

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 26.04.2019 11:32
von Häns
Leute wie Du, @neu_hier, wären froh und dankbar, wenn sie bei der Suche anhand Titel mit aussagekräftigen Stichworte wie "Datei von String auf HTML" entsprechende Lösungen finden können, und nicht anhand deines Titels "heute mal wieder...".

Es wäre daher nett, wenn Du den Titel änderst. Die anderen Neulinge oder sonstigen alten Säcke wie mich wären dankbar. 8)

Gruß, Häns

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 27.04.2019 03:42
von Toshy
Das Thema hat sich jetzt zwar erledigt, für einen Neuling möchte ich allerdings noch etwas anmerken:

Code: Alles auswählen

         While Eof(#loadfilenum) = 0
            x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))   
          ;  x$ = x$ + ReadString(#loadfilenum, flagg)
           
          Wend
Wenn du nun eine 100kb Datei hast, sind das "rund" 100 000 Bytes.
nutzt man

Code: Alles auswählen

x$ = x$ + Chr(ReadCharacter(#loadfilenum, flagg))  
wird nun ein character, also EIN oder ZWEI Bytes auf einmal eingelesen.
Das bedeutet auch, die Schleife läuft 50 000 mal oder 100 000 mal durch. Und immer wird nur ein Byte oder zwei gelesen!!

nutzt man

Code: Alles auswählen

x$ = x$ + ReadString(#loadfilenum, flagg)
Wir im korrekten Falle (Flag siehe oben) die ganze Datei auf eimal geladen. Wenn ich mich nicht irre, wird geladen bis ein EOL kommt, was wohl ein Nullbyte ist oder eventuell UTF oder so kann es auch was anderes sein. ich errinnere mich da nicht.

1. Wird hier auf jeden FAll in EINEM BLOCK gelesen (es sei den, was hier so scheint ein EOL in der Mitte steht) und das geht natürlich schneller. bei SSD merkt man es etwas weniger als bei normalen HDDs. bemerkbar ist es dennoch.
2. wird bei readchar jedes byte ausgelesen und gespeichert (außer nullbytes vermutlich). bei readstring allerdings nicht, falls eol im text sind. und diese werde dann auch nicht mehr im string gespeichert, da es "steuerzeichen" für PB sind (vereinfacht gesagt). es wird also nicht eins zu eins kopiert.

Was mir jetzt in den Sinn kommt ist allerdings, weshalb sind in der das EOLs drinn!? Das weißt doch auf einen FEHLER hin.
Entweder in der Datei, oder was ich eher vermute in deinem Code. Vermutlich nutzt dein kompeliertes PRogramm einen anderen Zeichensatz als die Datei!

Ich würde das noch mal überprüfen, alten Code nehmen der nicht ging und mal raus finden woran es lag.

Ach ja, und wie schon jemand gebeten hat. Passe den Titel deine ersten Beitrages mal an. einfach im Beitrag auf "ändern" klicken.

So was wie "[erledigt]readstring / readchar HTML und RTF auslesen. Problem."

Re: Heute wieder mal ein "Wie macht man das eigentlich?"

Verfasst: 27.04.2019 07:15
von H.Brill
1 KB = 1024 Byte
EOL = END OF LINE
Das ist ein Chr(13) + Chr(10) -> LINEFEED
So wird in Textdateien das Ende einer einzelnen Zeile markiert.

EOF = END OF FILE
Markiert das Ende einer Datei.

Das NULLBYTE markiert nur das Ende eines Strings in PB.
Also muß man aufpassen, was man mit welchen Lesebefehlen
aus einer Datei liest. Bei ReadString handhabt PB das so, daß
man bis ans Ende der Zeile den String bekommt.

Während ReadCharacter entsprechend des Formats (Ascii, Unicode, Utf8)
ein oder mehr Zeichen lesen kann, liest ReadByte nur ein einzelnes Zeichen.
Also auch immer beachten, wie die Datei codiert ist (Ascii, utf8, Unicode).