Dateiinhalt dynamisch erfassen und speichern

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Piwo
Beiträge: 27
Registriert: 05.08.2012 22:40

Dateiinhalt dynamisch erfassen und speichern

Beitrag von Piwo »

Hi,

ich bin an einem programm dran welches den Inhalt jeder Datei unabhängig ihrer Größe, Inhalts oder ihrer Kodierung erfassen, in eine variable speichern, ggf verändern und die modifizierte datei wieder neu abspeichern soll.
Habe mir gedacht, da das programm nicht nur textdateien sondern auch binäre dateien, bilder etc. lesen soll wäre es wohl am sinnvollsten wenn man wie in einem hex-editor die datei bitweise ausließt und die bytes hexadezimal abspeichert.
Weiß jedoch nicht ob ich dynamisch immer jeweils 8 bytes (zum beispiel) in ein stringarray-speichern soll, die gesamte datei hexadzimal in eine sehr lange string-variable speichern soll oder sonst irgendeine andere lösung (structure?) dafür überlege.
Hätte hier jemand eine idee welches dieser konzepte das effektivste wäre und mit welchen funktionen ich das am besten durchführe?

Ich hoffe ich habe das problem ausführlich genug beschrieben, ansonsten einfach nachfragen ^^

Danke und im vorraus :)
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von NicTheQuick »

Dafür gibt es Memory:

Code: Alles auswählen

Procedure FileToMemory(file.s)
	Protected *memory
	Protected fileId.i
	Protected fileSize.i
	
	fileId = ReadFile(#PB_Any, file)
	If (Not fileId)
		ProcedureReturn #False
	EndIf
	
	fileSize = Lof(fileId)
	
	*memory = AllocateMemory(fileSize, #PB_Memory_NoClear)
	If (Not *memory)
		CloseFile(fileId)
		ProcedureReturn #False
	EndIf
	
	If (ReadData(fileId, *memory, fileSize) <> fileSize)
		CloseFile(fileId)
		FreeMemory(*memory)
		ProcedureReturn #False
	EndIf
	
	CloseFile(fileId)
	
	ProcedureReturn *memory
EndProcedure

Define *buffer = FileToMemory("/home/nicolas/game1")

If *buffer
	Debug PeekS(*buffer)
	FreeMemory(*buffer)
EndIf
Allerdings kannst du damit keine Dateien öffnen, die größer sind als dein verfügbarer Arbeitsspeicher bzw. unter Windows größer als 2 GB sind. Da liegt nämlich dann die Grenze. Ab dann braucht man ein anderes Vorgehen.

//Edit: Jetzt auch mit Define.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von ts-soft »

Protected im MainScope?
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von NicTheQuick »

ts-soft hat geschrieben:Protected im MainScope?
Ja, das kommt davon, wenn man mal eben was umschreibt ohne es zu testen.
Benutzeravatar
Piwo
Beiträge: 27
Registriert: 05.08.2012 22:40

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von Piwo »

Zunächst mal danke für die schnelle Antwort,
den Codeteil habe ich verstanden und angewandt. Dateien mit klarem text wurden auch richtig und fehlerfrei angezeigt. Es trat bei binärdateien jedoch das problem auf, dass anstelle eines hexadezimales gesamten codes, mir nur 2 einzelne buchstaben angezeigt wurde. Ist der PeekS-befehl in diesem fall vielleicht die fehlerquelle?
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von NicTheQuick »

Na klar. Das war auch nur zu Demonstrationszwecken. PeekS wandelt einen Speicherbereich in einen String um. Und jeder String in PB endet mit einem Nullbyte. Das heißt, wenn das dritte Byte in deiner Datei eine 0 ist, dann ist der resultierende String auch nur zwei Zeichen lang.

Aber wenn man mit Binärdaten arbeiten will, nutzt man auch Memory in Zusammenhang entweder mit den zahlreichen Peek- und Poke-Befehlen oder wendet gleich Zeigerarithmetik an. Wenn du jedes Bytes als Hex dargestellt haben willst, dann schreibst du eben Debug Hex(PeekA(*buffer + OFFSET)) und OFFSET gibt in dem Fall das entsprechende Byte an. Mit einer For-Schleife kannst du dir dann auch einen String bilden, der alle Bytes hexadecimal in einen String schreibt.
Benutzeravatar
Kiffi
Beiträge: 10725
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von Kiffi »

ich persönlich würde ja SQLite empfehlen, welches von PB nativ unterstützt wird.
SQLite frisst so ziemlich alles und man braucht sich nicht umständliche Strukturen
auszudenken. Das bisschen SQL, was man dafür benötigt, ist schnell erlernt.

just my 2 cents ... Kiffi
a²+b²=mc²
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von NicTheQuick »

Ich glaube nicht, dass er strukturierte Daten speichern will. Laut seinem ersten Post will er eher alle möglichen Dateien einlesen können, ähnlich eines Hexeditors oder so.
Benutzeravatar
Kiffi
Beiträge: 10725
Registriert: 08.09.2004 08:21
Wohnort: Amphibios 9

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von Kiffi »

NicTheQuick hat geschrieben:Ich glaube nicht, dass er strukturierte Daten speichern will. Laut seinem ersten Post will er eher alle möglichen Dateien einlesen können, ähnlich eines Hexeditors oder so.
achso, ja dann nichts für ungut.

Grüße ... Kiffi
a²+b²=mc²
Benutzeravatar
Piwo
Beiträge: 27
Registriert: 05.08.2012 22:40

Re: Dateiinhalt dynamisch erfassen und speichern

Beitrag von Piwo »

Hatte mit dieser methode einige schwierigkeiten, hab daher eine etwas andere lösung gefunden die an für sich auch funktioniert.
Meine methode sieht vereinfacht etwa so aus:

Code: Alles auswählen

readfile(0, "<filepath>")
fileInHex.s = ""

while eof(0) = 0
 fileInHex = fileInHex + Hex(readCharakter(0))
wend
Wie man sieht lese ich byte-weise jeden charakter der datei aus, kodiere es in hexadezimale schreibweise und füge sie einzeln dem string hinzu. Der plan dahinter ist, dass ich nach ablauf des prozesses die komplette datei hexadezimal in in einer variable gespeichert hab.
Das funktioniert auch bis auf ein problem:
Der ablauf des prozesses ist schrecklich langsam. Dateien von nur ein paar kilobyte brauchen über eine minute.

Jemand eine idee woran das liegt oder wie ich das bedeutend beschleunigen könnte?
Antworten