Große Textdatei mit NullBytes einlesen

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Deluxe0321
Beiträge: 336
Registriert: 19.05.2006 00:31
Kontaktdaten:

Große Textdatei mit NullBytes einlesen

Beitrag von Deluxe0321 »

Servus,

Ich muss für ein kleines projekt große TextDateien (logs) einlesen, leider können diese des öfteren NullBytes enthalten.
Soweit zu bunt, zur Zeit löse ich das so:

Code: Alles auswählen

Procedure.s FileToString(File.s)
  Protected *memory, String.s, Bom.i 
  If FileSize(File.s) > 0
    FileID.i = ReadFile(#PB_Any,File.s)
    Bom.i = ReadStringFormat(FileID.i)
    If FileID.i
      *memory = AllocateMemory(FileSize(File.s))
      If *memory
      ReadData(FileID.i,*memory,FileSize(File.s))
      ;ONLY ASCII  for now
      Repeat
      String.s = PeekS(*memory,FileSize(File.s),Bom.i)
        If MemorySize(*memory) > Len(String.s)
          PokeC(*memory + Len(String.s),1)  
          Debug "ZeroByte"
        Else
          Break
        EndIf
      ForEver
      FreeMemory(*memory)
      EndIf
      ProcedureReturn String.s
    EndIf
  EndIf 
EndProcedure
Jedoch ist das bei Dateien mit vielen NullBytes oder sehr großen (die files haben max 20MB) quälend langsam.
Kennt jemand von ech eine schnellere Methode?

Beste Grüße,
Deluxe0321
Ich habe keine Lösung, aber ich bewundere das Problem.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 7031
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Große Textdatei mit NullBytes einlesen

Beitrag von STARGÅTE »

Zuerst mal ist es keine Text-Datei mehr, wenn es Null-Bytes hat.

Dein Code ist langsam, weil du jedes mal wieder von Position 0 bis zum nächsten NullByte versuchst einen String zu lesen.
Du kannst den Code beschleunigen, indem du die Null-Bytes direkt im Speicher suchst und ersetzt, zB:

Code: Alles auswählen

For *I.Byte = *memory+MemorySize(*memory)-1 To *memory Step -1
  If *I\b = 0
    *I\b = 1
  EndIf
Next 
und dann erst am ende nur ein mal PeekS() anwendest.

Bei 20MB und NULL-Bytes solltest du dir aber gedanken machen, ob ein String überhaupt der richtige Container für dein Log-File ist, denn wenn du damit dann arbeiten willst (Suchen, Ersetzen, Weitergeben) kann ich dir gleich sagen, dass alles wieder "ewig" dauern wird. Ein String ist nunmal nur eine Zeichenkette und kein "Buch"

Edit: Code noch mal angepasst
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Deluxe0321
Beiträge: 336
Registriert: 19.05.2006 00:31
Kontaktdaten:

Re: Große Textdatei mit NullBytes einlesen

Beitrag von Deluxe0321 »

Seruvs STARGÅTE,
das Stück Code funktioniert prima! Ich danke dir.

Die Textdatei ist verschlüsselt und muss vorher entschlüsselt werden (Das Programm ist nicht von mir und baut meistens Mist, darum die NullBytes!).

Warum einlesen als String?:
Naja, ich lese die Datei ein, und füge für jedes #CRLF$ in der Log ein Element in eine Liste.
Diese Liste lasse ich dann in Parts geteilt, gethreaded, mit ein paar hundert "Suchstrings" (aus einer DB) abgleichen (jeder Part hat bestimmte "Suchstrings").
Kurz: ich durchsuche die Log nach bekannten oder häufigen Fehlern.

Ich hätte die Liste auch mit ReadString(FileID.i) füllen können, aber die Geschwindigkeit ist so noch schlechter ;)
Falscher weg hin oder her, das programm ist nun, dank deines Code so gut wie sofort offen.

Beste Grüße,
Deluxe0321
Ich habe keine Lösung, aber ich bewundere das Problem.
Antworten