PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : binärdateien mit c kopieren



doomcalyptica
21-03-2005, 14:55
hallo programmierfreunde :)

ich kann mit C sowohl dateien in formaierten zustand öffnen und manipulieren als auch dateien im low level bereich öffnen und verändern. ich dachte, ich könnte eine ausführbare datei öffnen und in eine andere leere datei schreiben, quasi kopieren. wenn ich die neue datei ausführen möchte, dann fehlt immer irgendwas ...

ein beispiel mit high level:


#include <stdio.h>

int main() {
FILE *src, *dest;
char swap[1000000];
int c;

src=fopen("c:\\tippen.exe","r+b");
dest=fopen("c:\\neu.exe","w+b");

if(src==NULL && dest==NULL)
fprintf(stderr,"FEHLER !!!!!!!!!!!\n");

while((c=fgetc(src))!=EOF) {
fputc(c,dest);
}

fclose(dest);
fclose(src);

return 0;
}

das hier scheint zu funktionieren :)
leider kann ich das von low level nicht gerade behaupten ...
ich brauche für die low level, die funktion "open", damit ich ein "handle" habe, dieser ist ja nichts weiter als ein integerwert ... desweiteren kenne ich nur die beiden funktionen "write" und "read" um zeichen in ene datei zu schreiben ... das dumme ist nur, das ich explizit structuren brauche, die eine feste größe haben müssen und zur laufzeit des programms nicht bekannt sind :( ... kennt da jemand eine alternative ???

please help

nobody0
21-03-2005, 16:26
Einfach open, close, read und write nehmen; da braucht man keine Struktur.
Allerdings ist es egal ob man es damit oder fopen, fclose, fgetc und fputc macht; das Ergebnis ist dasselbe.

panzi
21-03-2005, 17:31
Einfach open, close, read und write nehmen; da braucht man keine Struktur.
Allerdings ist es egal ob man es damit oder fopen, fclose, fgetc und fputc macht; das Ergebnis ist dasselbe.
Oder fread und fwrite.
Jedenfalls ist zeichenweise lesen die unperformanteste lößung. ;)

nobody0
21-03-2005, 22:49
Oder fread und fwrite.
Jedenfalls ist zeichenweise lesen die unperformanteste lößung. ;)

Ja, es ist ungefähr doppelt schneller in 8-Byte-Blöcken einzulesen und Funktionen wie cp arbeiten in noch größeren Blöcken (n*512).
Allerdings muß man das Dateiende meist extra behandeln, denn das ist ja nur selten ein ganzzahliges Vielfaches der Blockgröße.

panzi
22-03-2005, 01:38
fread sagt dir eh wieviel du gelesen hast. den wert übergibst einfach fwrite.

nobody0
22-03-2005, 08:32
fread sagt dir eh wieviel du gelesen hast. den wert übergibst einfach fwrite.

Klar, aber das ist eben etwas Mehraufwand (ggü. fgets/fputs), den man nicht vergessen darf, wenn es funktionieren soll.
Wenn die Daten Blockweise statt zeichenweise verarbeitet werden, kann der letzte Block kleiner sein; beim zeichenweisen Einlesen hat man diesen Fall aber nicht.

panzi
22-03-2005, 12:19
Klar, aber das ist eben etwas Mehraufwand (ggü. fgets/fputs), den man nicht vergessen darf, wenn es funktionieren soll.
Wenn die Daten Blockweise statt zeichenweise verarbeitet werden, kann der letzte Block kleiner sein; beim zeichenweisen Einlesen hat man diesen Fall aber nicht.
Nur fgets/fputs kann man hier ja eh vergessen, zumal es um Binärdaten geht. Und fread/fwrite mit gscheiter Blockgröße ist eben performanter (-> weniger Aufwand), als Zeichenweises leßen. Probiers aus.

nobody0
22-03-2005, 12:26
Nur fgets/fputs kann man hier ja eh vergessen, zumal es um Binärdaten geht.

Unsinn; im ANSI-C sind fgets/fputs byte input/output functions und es gibt etliche Programme, die diese auch verwenden.

Blockweise ist 's aber besser.

panzi
22-03-2005, 17:49
Unsinn; im ANSI-C sind fgets/fputs byte input/output functions und es gibt etliche Programme, die diese auch verwenden.

Blockweise ist 's aber besser.
Und was wenn ein \0 im Binärdatenstrom ist?

nobody0
22-03-2005, 21:49
Und was wenn ein \0 im Binärdatenstrom ist?

Nichts; was sollte da passieren?
Du kannst es ja selbst mit
dd if=/dev/zero of=foo.bin bs=8 count=1
testen; EOF (ist immer größer oder kleiner als der Wertebereich von char implementiert) ist erst nach dem letzten Byte erreicht.
Wenn Du einen Compiler findest, der nicht so ein Programm erstellt, ist das kein ANSI-C-Kompiler und garantiert uralt.
Deshalb ist der Modus mit +b bei fgets/fputs redundant.

panzi
23-03-2005, 00:41
Mit fgets liesßt man in einen char-buffer ein, also quasi einen String. Nun nehmen wir also an der Input ist ein Binärdatenstrom der ein \0 und auch noch mehr Zeichen dahinter enthält.
Jetzt übergeben wir den gelesenen buffer fputs, was macht es damit? Nun es schreibt nur bis zum ersten \0. Siehst du worauf ich hinaus will?

Und ich schätze das dd entweder fread/fwrite oder read/write verwenden wird, und nicht fgets/fputs.

quinte17
28-03-2005, 14:10
hallo programmierfreunde :)


#include <stdio.h>

int main() {
FILE *src, *dest;
char swap[1000000];
int c;

src=fopen("c:\\tippen.exe","r+b");
dest=fopen("c:\\neu.exe","w+b");

if(src==NULL || dest==NULL)
fprintf(stderr,"FEHLER !!!!!!!!!!!\n");

while((c=fgetc(src))!=EOF) {
fputc(c,dest);
}

fclose(dest);
fclose(src);

return 0;
}

please help
ich würde da statt den && ein || setzen...
den rest so wie schon beschrieben ändern ^^

nobody0
28-03-2005, 17:29
Ja, stimmt.
Und wenn das Programm nicht richtig funktioniert, sollten auch mal die anderen Rückgabewerte auf Fehler überprüft werden, also die von fputc, fclose.