Dateigröße ermitteln



  • MasterCounter schrieb:

    Diese Lösung ist mir ja bekannt, aber das verhaklten von fseek mit SEEK_END ist laut Standard undefiniert, darum wäre meine Lösung doch eigentlich sicherer oder?

    Was willst Du eigentlich machen? Die Datei in den Speicher übertragen?



  • Ich wollte einfach nur eine sichere Lösung finden, um die Dateigröße zu ermitteln, denn diese braucht man ja um die Datei in ein char* oder ähnliches zu lesen. Was hältst du also von meiner Lösung? Müsste doch eigentlich sicher sein oder?



  • int Size;             
    
    fseek( <DATEI>, 0, SEEK_END );			//Springt ans Ende Der Datei
    Size = ftell( <DATEI> );      			   //Ermittelt Größe in Bytes
    fseek( <DATEI> , 0, SEEK_SET );        //Springt wieder an Anfang (Wichtig!)
    


  • MasterCounter schrieb:

    Ich wollte einfach nur eine sichere Lösung finden, um die Dateigröße zu ermitteln, denn diese braucht man ja um die Datei in ein char* oder ähnliches zu lesen. Was hältst du also von meiner Lösung? Müsste doch eigentlich sicher sein oder?

    Ist nicht besonders schön, weil man die Datei eben zweimal abklappert, und außerdem kann man theoretisch Fälle konstruieren, wo while(fgetc(f)!=EOF) nicht erwartungsgemäß funktioniert (weil int und char gleich breit sind und man EOF nicht von einem gültigen char gleichen Zahlenwertes unterscheiden kann). Das ist allerdings ziemlich paranoid und somit nur zu berücksichtigen, wenn man maximal portabel bleiben will (sonst macht man die ganze Zeit Klimmzüge um ISO-konform zu bleiben). Also kann man das schon prinzipiell so machen, wie Du dir das vorstellst, aber man kann auch einfach mit realloc immer ausreichend Speicher bereitstellen, wenn's dir nur darum geht, die Datei in einen 'char*' zu bekommen.



  • wie sähe das dann mit realloc aus?



  • void* xrealloc(void *mem, size_t sz) {
        void *p = realloc(mem, sz);
    
        if (!p) {
            free(mem);
            ...
            exit(EXIT_FAILURE);
        }
    
        return p;
    }
    
    char *fgetfile(FILE *f) {
        char *p, *q;
        size_t mem_sz = INIT_MEM; /* beliebige Konstante */   
        size_t pos = 0;
    
        p = 0;
        while (1) {
             p = xrealloc(p, mem_sz);
    
             q = p + pos;
    
             while (q != p + mem_sz) {
                  int c = fgetc(f);
    
                  ++pos;
    
                  if (c == EOF) {
                      *q = '\0';
                      return p;
                  }
                  else *q++ = c;
             }
    
              mem_sz *= 2; /* Speicherbereich verdoppeln */
         }
    
         return 0; /* nie erreicht, wenn der Quelltext so tut, wie ich mir das vorstelle */
    }
    

    Das ist jetzt einfach so runtergehackt, also vermutlich ist irgendwo noch ein Fehler drin. Außerdem kann man die Sache etwas beschleunigen, indem man andere Leseroutinen statt fgetc verwendet ...

    Hast Du wirklich noch nie einen Anwednungsfall für realloc gesehen?



  • doch schon, aber in dynamischer speicherplatzverwaltung bin ich noch nicht so fit... hab vorher alles über malloc gemacht, darum hab ich nach einer sicheren möglichkeit gesucht die dateigröße zu ermitteln, vielen dank erstmal an dich!



  • MasterCounter schrieb:

    Diese Lösung ist mir ja bekannt, aber das verhaklten von fseek mit SEEK_END ist laut Standard undefiniert, darum wäre meine Lösung doch eigentlich sicherer oder?

    Das ist aber imo ziemlich paranoid. Der Standard sagt ja nur soviel, dass eine Implementation von SEEK_END für binäre Streams nicht unterstützt werden muss, bzw in erwarteter Weise funktionieren wird. Mit Unix oder Windows wird man da aber kaum Probleme haben.
    Ansonsten hilf dir vielleicht das weiter

    So, to go back to the original question, the best chance of "portably"
    obtaining the (physical) size of a file (in bytes) is:

    long filesize(char *filename) 
    {
     long size;
     FILE *fp;
    
     if ((fp = fopen(file, "r")) == NULL) return -2;  
     fclose(fp);
     if ((fp = fopen(file, "ab")) == NULL) return -3;
     size = ftell(fp);
     fclose(fp)
     return size;
    }
    

    Note that there are three error codes:

    -1: ftell() has failed, check errno for further details
    -2: the file doesn't exist or is read protected
    -3: the file exists, but is write protected

    Die Vorgehensweise hat aber einen nicht unerheblichen Nachteil, du brauchst Schreibzugriff.



  • Dieser Beitrag wurde gelöscht!


  • Dieser Beitrag wurde gelöscht!

Anmelden zum Antworten