Seite 1 von 1
Daten mit "0" als string verarbeiten
Verfasst: 10.09.2009 09:49
von Syntacks_Error
Möchte aus Nicht-Text-Dateien, die aber hier und da auch Text eingebettet haben, den Text extrahieren.
Dummerweisen enthalten die Dateien jede Menge "0", was die Stringfunktionen wohl als "Stringende" verstehen und meinen, ihre Arbeit da einstellen zu sollen.
Einzige gefundene Lösung bislang: Datei einlesen, bitweise auslesen und die "0" aussortieren:
Code: Alles auswählen
file_size = FileSize(dateiname$)
file_ID = readfile(#pb_any,dateiname$)
*Memory_ID = AllocateMemory(file_size)
Datei_lesen = ReadData(file_ID, *memory_ID, file_size)
If datei_lesen
For x = 0 To file_size
a.c = PeekC(*memory_ID + x)
If a.c > 0
test$ = test$ + Chr(a.c)
EndIf
Next
EndIf
debug "Teststring: " + left(test$,100)
Leider ist diese Methode unziemlich langsam. Gibt es Besseres?
Re: Daten mit "0" als string verarbeiten
Verfasst: 10.09.2009 10:15
von DarkDragon
Probiers mal damit:
Code: Alles auswählen
file_size = FileSize(dateiname$)
file_ID = ReadFile(#PB_Any, dateiname$)
*memory.Character = AllocateMemory(file_size)
datei_lesen = ReadData(file_ID, *memory, file_size)
If datei_lesen
test$ = Space(file_size / SizeOf(Character))
*testPointer.Character = @test$
*memoryEnd = *memory + file_size
While *memory < *memoryEnd
If *memory\c > 0
*testPointer\c = *memory\c
*testPointer + SizeOf(Character)
EndIf
*memory + SizeOf(Character)
Wend
test$ = Left(test$, *testPointer - @test$)
EndIf
Debug "Teststring: " + Left(test$,100)
Testen konnte ich es nicht, da ich keine Datei hab. Generell solltest du aber ein paar Abfragen mehr reinsetzen zum Beispiel was das öffnen der Datei betrifft. Ich würde auch auf Lof() statt FileSize setzen, da die Datei zwischendrin gelöscht werden könnte und dann willst du einen Speicherbereich von -1 reservieren.
Re: Daten mit "0" als string verarbeiten
Verfasst: 10.09.2009 10:22
von Rokur
Wie wärs wenn du anstatt dem Zeichenweisen zusammenbasteln alle 0-Bytes durch was anderes ersetzt? Dann kannst du anschliessend den ganzen Speicherbereich verwenden.
Also so in der Art:
Code: Alles auswählen
a.b = PeekB(*memory_ID + x)
If a = 0
PokeB(*memory_ID + x, 255)
EndIf
test$ = PeekS(*memory_ID, file_size)
Anstatt 255 kannst du natürlich auch irgendwas anderes Einsetzen, z.B. Leerzeichen oder so.
PS: Vorsicht beim Datentyp Character, bei Unicode hat der 2 Bytes, ansonsten 1 Byte!
Re: Daten mit "0" als string verarbeiten
Verfasst: 10.09.2009 12:23
von Syntacks_Error
Verblüffend, vielen Dank. Das ist gefühlte 1000* schneller als als meine Geschichte. Wieso eigentlich?
Habe noch vier

Fragen dazu:
Wie kriege ich den Speicher wieder frei? freemem(*memory) wirft bei allen möglichen Variationen (incl *memory.character) einen Fehler aus.
Was bedeutet eigentlich dieses \c?
Müßte es nicht vielleicht "test$ = Space(file_size *SizeOf(character))" statt "test$ = Space(file_size/SizeOf(character))" heißen, wenn unicode berücksichtigt werden soll?
Offenbar kann man beim rechnen den neuen wert weglassen, also "x+1" statt "x = x+1"?
Re: Daten mit "0" als string verarbeiten
Verfasst: 10.09.2009 12:30
von DarkDragon
Syntacks_Error hat geschrieben:Verblüffend, vielen Dank. Das ist gefühlte 1000* schneller als als meine Geschichte. Wieso eigentlich?
Habe noch vier

Fragen dazu:
Wie kriege ich den Speicher wieder frei? freemem(*memory) wirft bei allen möglichen Variationen (incl *memory.character) einen Fehler aus.
Was bedeutet eigentlich dieses \c?
Müßte es nicht vielleicht "test$ = Space(file_size *SizeOf(character))" statt "test$ = Space(file_size/SizeOf(character))" heißen, wenn unicode berücksichtigt werden soll?
Offenbar kann man beim rechnen den neuen wert weglassen, also "x+1" statt "x = x+1"?
*memory ist nach der Routine verändert, also müsste man es so machen:
Code: Alles auswählen
file_size = FileSize(dateiname$)
file_ID = ReadFile(#PB_Any, dateiname$)
*memory.Character = AllocateMemory(file_size)
*oldMemory = *memory
datei_lesen = ReadData(file_ID, *memory, file_size)
If datei_lesen
test$ = Space(file_size / SizeOf(Character))
*testPointer.Character = @test$
*memoryEnd = *memory + file_size
While *memory < *memoryEnd
If *memory\c > 0
*testPointer\c = *memory\c
*testPointer + SizeOf(Character)
EndIf
*memory + SizeOf(Character)
Wend
test$ = Left(test$, *testPointer - @test$)
EndIf
Debug "Teststring: " + Left(test$,100)
FreeMemory(*oldMemory)
Die Pointer sind ja hier Strukturiert. Wenn du Alt+S drückst siehst du die vordefinierten Strukturen. Darunter Character mit c.c

. Man greift also auf den Inhalt an der Adresse zu als ob es ein Character wäre.
file_size ist die komplette Dateigröße, mehr Raum wird nicht benötigt, also ist "*" falsch. Da wir ja in der Datei aber maximal file_size / SizeOf(Character) Daten vom Typ Character in Reihe haben stimmt das "/".
Ja beim Rechnen kann man das = weglassen so wie du es sagtest.
Re: Daten mit "0" als string verarbeiten
Verfasst: 10.09.2009 12:42
von Syntacks_Error
Aja. Vielen Dank nochmal, auch an den anderen Poster.