Dateien mit C-Programm kopieren



  • Nochmals danke für eure Posts! Vor allem MAG hat mir sehr bei meinem Problem das Rat neu zu erfinden geholfen, auch, wenn er mich genauso, wie Diamond davon überzeugen wollte, auf fertige Bibliotheksfuntktionen zurückzugreifen. Dies tue ich ja auch meistens nur wollte ich diesmal rein aus sportlichem Ehrgeiz darauf verzichtem. Und? Es ist mir fast genau 24 Std. später gelungen eine Version zu schreiben, die wirklich nur mit fgetc und fputc eine Datei, beliebiger Größe kopiert. Hier das 'leicht' veränderte Listing als Beweis dazu :D:

    #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);
    }
    


  • beliebig? kopier mal eine datei groesser 1 gig. wenn du glueck hast, stuerzt dein programm ab.

    du solltest wissen:
    * das OS benutzt sehr wahrscheinlich puffer, also wird jedes fgetc/fputc durch einen puffer geschleift und der schreib/lesekopf wird nicht belastet.
    * zeichenweise ganze dateien kopieren ist grober unfug, weil du so rechenzeit verschwendest
    * ein schreib/lesepuffer so gross wie die datei ist grober unfug. eine angemessene groesse von mehreren KB oder MB tuts auch.



  • * die Datei zweimal lesen um sie einmal zu kopieren ist.....



  • ... purer wahnsinn!

    ich glaube, die funktion habe ich unterbewusst ueberlesen, um mir die qualen zu ersparen...



  • Hallo c.rackwitz, hallo LordJackson!

    Ihr habt ja recht mit dem Programm da oben kann man nur "effektiv" Dateien kopieren, die kleiner sind, als der freie Arbeitsspeicher, der einem zur Verfügung steht. Bei größeren Dateien wird der Prozess geswappt und alles muss dreimal gelsesn und doppelt geschrieben werden - und das alles über die HD. Dass dies nicht der Königsweg ist weiß ich. Deshalb war mein primäres Ziel ja auch das erste Listing zu verwenden, das einen Buffer verwendet, in den bei jedem Durchgang x - im Beispiel 21 - Zeichen eingelsesen werden unm diese dann gleich wieder in die Datei zu schreiben. Leider scheint sich in den Schleifen ein Fehler zu verstecken. Findet ihn, dann verwende ich das bessere Listing oder macht mir nen Vorschlag, wie man eure Vorschläge in Code realisieren kann.

    PS: Zu meiner getFLEN()-Funktion kann ich euch nur fragen, was ihr meint, was fseek wohl macht? Intern wird die funktion doch genau so arbeiten, wie meine im obigen Listing, nämlich vom ersten bis zum letzten Zeichen die vorliegende Datei auszulesen und auf EOF zu warten.



  • #include <stdio.h>
    
    #define BUFLEN 1024
    
    int main(int argc, char **argv)
    {
        char buf[BUFLEN];
        int numread;
        FILE *inf, *of;
    
        if (argc < 3)
        {
            puts("not enough arguments!");
            puts("program <infile> <outfile>");
            return 1;
        }
    
        if (!(inf = fopen(argv[1], "rb")))
        {
            puts("error: fopen(infile);");
            return 2;
        }
    
        if (!(of = fopen(argv[2], "wb")))
        {
            puts("error: fopen(outfile);");
            fclose(inf);
            return 3;
        }
    
        while (!ferror(inf) && (numread = fread(buf, 1, BUFLEN, inf)))
        {
    		printf("%d read\n", numread);
    		fwrite(buf, 1, numread, of);
    		if (feof(inf) || ferror(of))
    			break;
        }
    
        fclose(of);
        fclose(inf);
    
        return 0;
    }
    


  • Arthur_Dent schrieb:

    [...], was ihr meint, was fseek wohl macht? Intern wird die funktion doch genau so arbeiten, wie meine im obigen Listing, nämlich vom ersten bis zum letzten Zeichen die vorliegende Datei auszulesen und auf EOF zu warten.

    Äh, nein? 😃



  • fseek machts anders und funktioniert garantiert nicht SO (mit feof()).

    http://www-ccs.ucsd.edu/c/stdio.html#fseek



  • Hallo!
    Ich geb ja zu, dass die letzten Listings nicht so der Brenner waren, aber jetzt habe ich es endlich geschafft, das erste zu Perfektionieren. Wahrscheinlich werdet ihr lachen, was ihr im Zweifelsfalls auch schon jetzt tut, aber es funktioniert wirklich - und das nur mit fgetc und fputc. Damit ihr aber nicht sagen könnt, dass ich vollkommen unbelehrbar bin habe ich sogar fseek benutzt, um die Dateilänge zu bekommen.

    Nun sied mal ehrlich, ist dieses Listing nicht der Hammer?

    #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);
    }
    

    PS: Interessanterweise lag das Problem in der ersten for-Schleife.



  • ersetz doch mal deinen goto-loop mit einem do {} while ();



  • Das ist ohne goto auch ziemlich einfach und sieht dann wie folgt aus:) :

    #include <stdio.h>
    #include <stdlib.h>
    #define BUFFER 4096
    
    int main(int argc, char *argv[]) {
      int i, flen,  len=BUFFER, c[BUFFER+1];
      FILE *in=fopen(argv[1], "r");
      FILE *out=fopen(argv[2], "w");
      fseek(in, 0, SEEK_END);
      flen=ftell(in);
      rewind(in);
      while(BUFFER==len) {
      for(i=0; i<=BUFFER && flen>0; i++, flen--) { c[i]=fgetc(in); len=i; }
      for(i=0; i<=len; i++) fputc(c[i], out);
      }  fclose(in); fclose(out);
    }
    

Anmelden zum Antworten