Dateien mit C-Programm kopieren

Jan-Michael

Jan-Michael

Aktives Mitglied
Thread Starter
Dabei seit
28.02.2005
Beiträge
397
Reaktionspunkte
0
Hallo Leute!

Da ich in den letzten Tagen ein bischen zuviel Zeit hatte habe ich mich aufgemacht, das cp-Kommando der Bash zumindest annährend in der Funktion zu klonen. Prinzipiell ist das ja auch kein Problem und mit ein paar Zeilen zu bewältigen. Nur ist eine Lösung der Sorte:

int c; while((c=fgetc(in)!=EOF) fputc(c, out);

nicht zwingend effektiv, da sich der Lese/Schreibkopf der HD zu oft hin-und herbewegen muss. Ein Buffer, wie ich ihn im folgenden Listing verwendet habe wäre da schon eine tolle Sache, wenn es da nich doch noch einen Fehler im folgenden Programm gibt, den ich selbst auch nach langer Suche nicht finden kann. Da ich aber schon solange herumüberlegt und probiert habe kann ich das Problem auch nicht mehr beiseite legen. Deshalb wäre ich euch für eine mögliche Lösung bzw. Erläuterung des Fehlers sehr dankbar.

Code:
#include <stdio.h>
#define BUFFER 20

int main(int argc, char *argv[]) {
  int c[BUFFER+1], i, len;
  FILE *in=fopen(argv[1], "r");
  FILE *out=fopen(argv[2], "w");
 read_write:
  for(i=0; ((c[i]=fgetc(in))!=EOF) && (i<=BUFFER); i++) len=i;
  for(i=0; i<=len; i++) fputc(c[i], out); 
  if(len==BUFFER) goto read_write;
  fclose(in); fclose(out);
}
 
fgetc liest jedes zeichen einzeln, warum verwendest du nicht fread?
 
Naja, computer sind heute ja nicht mehr so wie früher. Du kannst gerne mal Performance Checking machen, aber auch das Dateisystem hat einen Cache, und schreibt nicht jedes Byte sofort weg.

Gruss

Alex
 
Hallo!

@ oneOeight: Natürlich könnte ich auch Funktionen, wie fputs verwenden, die gleich ein ganzen Arsenal an Zeichen automatisch in den Puffer schreiben, unter sportlichen Gesichtspunkten hatte ich mir jedoch das Ziel gesetzt, das Programm mit etwas spartanischereren Mitteln zu schreiben.

@below: Stimmt, die HD hat auch nen Cache und da wird auch reingeschrieben, nur eben nich soviel, dass man mit dem cp-Kommando mitkäme. Wie aber schon oben gesagt nehme ich das obige Programm sportlich. Da geht es mit weniger um eine einfache, als um eine möglichst schnelle/performante Lösung. Das kann man dann doch nur erreichen wenn man gleich ganz viele Zeichen in den RAM schreibt. Klar, bei kleinen Dateien ist das egal, wenn man jedoch größere Archive mit über 50 MB kopieren will merkt man den Performanceverlusst durch den fehlenden Puffer schon.

PS: Bei dem obigen Listing übrigens noch anzumerken ist, dass Dateien kopiert werden - das Programm funktioniert also im Prinzip. Nur das 21. Zeichen wird jedesmal, wenn der Puffer voll ist nicht mehr mit geschrieben. So hat dann eine Datei mit ursprünglich 42 Zeichen nach dem Kopiervorgang nur noch 40 Zeichen.
 
Zuletzt bearbeitet:
Bin mir nicht sicher, ob das nun hilft... aber ich hatte mal ein ähnliches Problem. Die Lösung war: Öffnen der beiden Dateien im "Binär-Modus".

Lass es mich wissen, wenn es geholfen hat ;) Winn
 
Hallo Winn und danke für deinen Vorschlag!

Leider habe ich keine Ahnung, wie ich die beiden Dateien im binär-Modus mit C öffnen sollte und mich in der Zwischenzeit schon an einen anderen Lösungsansatz gemacht. Wenn du trotzdem noch an diesem interessiert bist - hier das Listing dazu:


Code:
#include <stdio.h>
#include <stdlib.h>

int getFLEN(FILE *fd) {
  int i, len;
  for(i=0; fgetc(fd)!=EOF; i++) len=i;
  return len;
}

int main(int argc, char *argv[]) {
  int i, len, c;
  int *s;
  FILE *in=fopen(argv[1], "r");
  FILE *out=fopen(argv[2], "w");
  len=getFLEN(in); rewind(in);
  if((s = (int*) malloc(len*sizeof(*s)))==NULL) return -1;
  for(i=0; i<=len; i++) (*s++)=fgetc(in);
  s-=len;
  for(i=0; i<len; i++) fputc(*s++, out);
  fclose(in); fclose(out);
}

Leider habe ich dabei immer noch das Problem, dass die komplette Datei in den RAM geladen wird :-(. Naja, wie auch immer - es funktioniert und das ist die Hauptsache :).

Ansonsten noch mal Danke für alle anderen Vorschläge.
 
Hallo Winn und danke für den Tipp. Leider vergisst das Programm auch beim Öffnen im Binärmode jedes letzte Zeichen im Buffer - ich tippe, dass dies mit den Bedingungen in der Schleiße oder mit den Funktionen fputc bzw. fgetc zusammenhängt. Trotzdem stellt sich für mich sogar bei dem neuen Listing noch ein Problem: Dateien werden nur richtig kopiert, wenn sie Textzeichen enthalten. Bei Archiven, jpegs oder Audiodaten wird zwar alles bis zum letzten Zeichen kopiert nur kann diese kopierte Datei dann nicht mehr mit einem normalerweise geeigneten Programm geöffnet werden. In Java gibt es für sowas den Datentyp byte. Gibt es in C einen äquivalenten Ausdruck, oder Datentyp, der anstelle von Textzeichen Bytes einliest?

PS: Habe auch schon mal versucht alles im Binärmode einzulesen. Hilft aber leider auch nix :(.
 
Hallo nochmal!!
Wie ich jetzt rausgefunden habe lag das Problem in der ersten Schleife versteckt. Wie auch immer kam der Compiler nicht mit der Zuweisung und dem gleichzeitigen Vergleich klar. Im Endeffekt sieht das komplette Programm dann wie folgt aus:

Code:
#include <stdio.h>
#include <stdlib.h>
#define BUFFER 1024

int main(int argc, char *argv[]) {
  int c[BUFFER+1], len, flen, i;
  FILE *in=fopen(argv[1], "r");
  FILE *out=fopen(argv[2], "w");
  fseek(in, 0, SEEK_END);
  flen=ftell(in);
  rewind(in);
 read_write:
  for(i=0; flen>0 && i<=BUFFER; i++, flen--) { c[i]=fgetc(in); len=i; }
  for(i=0; i<=len; i++) fputc(c[i], out);
  if(BUFFER==len) goto read_write;
  fclose(in); fclose(out);
}
 
Zurück
Oben Unten