2012-04-13 6 views
0

In meinem Projekt muss ich die freigegebene Datei in ein Verzeichnis kopieren, das Freigabe anruft. Meine Idee ist, das enthält dieser Datei Verwendung fgets und fputs zu kopieren:Malloc die Größe der Dateipufferbasis auf einer vorhandenen Datei

FILE *fp; 
int size; 
char *fileBuff 

fseek(fp,0,SEEK_END); 
size=ftell(fp); 
printf("Size of %s: %d bytes.\n",path,size); // print correct size 
fileBuff=malloc(size); // mallocate the file buffer 
printf("\nsize of file buffer is %d",sizeof(fileBuff)); //always print 4!! 
while(!feof(fp)){ 
    fgets(fileBuff,size,fp); // put into file buffer 

} 
printf("\nsize of file buffer is %d",sizeof(fileBuff)); // also print 4!! 

jedoch die Dateipuffer die Größe von Dateipuffer nicht mallocated werden kann, ist immer 4. was passiert?

Update: scheint es einige Missverständnisse zu haben. Die Größe von(), wenn ich nur überprüfen soll, ob etwas im Dateipuffer gespeichert ist. Ich versuche Strlen (fileBuff), und es gibt mir immer 1.

+1

Besser, 'fstat' zu verwenden, um die Größe der Datei eher zu finden, die zum Ende etc. sucht. –

Antwort

4

Das ist falsch: sizeof(fileBuff). Dies ist die Größe des Zeigers, der auf Ihrem System 4 ist.

Sie können sizeof nicht verwenden, um die Größe eines von malloc() zurückgegebenen Speicherblocks zu "extrahieren". Sie können nichts verwenden, um diese Größe zu extrahieren, es ist einfach nicht möglich in (Standard) C. Sie müssen den size Wert verwenden, d. H. Das Argument zu malloc(). Auch

, ftell() kehrt long, nicht int und beide malloc() und die verschiedenen E/A-Anrufe können fehlschlagen, die Sie berücksichtigen müssen.

Meiner Meinung nach ist es keine gute Idee, einen Puffer der Größe der Datei zu verwenden, um eine einfache Kopie zu machen; Es ist viel besser, einen "vernünftigen" Puffer zu verwenden (dessen genaue optimale Größe von vielen Faktoren abhängt) und dann wiederholte Lese-Schreib-Paare in einer Schleife zu machen, bis Sie durch die gesamte Datei gestreamt haben.

UPDATE Weitere Punkte über Ihren Code:

  1. Sie sprechen über strlen() verwenden, aber der Code zeigt sizeof nach dem fread() auch.
  2. Sie sprechen über die Verwendung von sizeof zu "überprüfen", wenn es etwas im Puffer gibt, ist dies nicht möglich; jeder Ausdruck mit sizeof wird immer zur Kompilierungszeit ausgewertet, es kann nicht verwendet werden, um dynamische Dinge wie das zu überprüfen. Und wieder können Sie es nicht verwenden, um die Größe eines Speicherblocks zu berechnen, der von malloc() zurückgegeben wird.
  3. Verwendung strlen() auf einem Puffer halten Datei funktioniert nur zuverlässig, wenn die Datei binär ist und enthält ein '\ 0' an seiner letzten Position, sonst haben Sie eine nicht abgeschlossene Zeichenfolge und strlen() möglicherweise undefiniert Verhalten aufrufen.
  4. Wie gesagt, Sie müssen überprüfen, ob malloc()NULL zurückgibt, was es tun wird, wenn es den angeforderten Speicherblock nicht zuordnen kann.

Außer flexible arrays in C99, aber lassen wir das ignorieren.

+0

danke so viel, aber warum kann ich den Dateipuffer malloc? nur wegen des Datentyps? Das Programm meldet keinen Fehler, aber es wird nichts in den Dateipuffer eingefügt. Es kann einfach nicht verfälscht werden – panda

0

Die Größe eines Zeigers (char *) auf (32-Bit) -Plattform ist immer 4.

Sie nicht sizeof, wie viel Speicher zu bestimmen, verwenden kann, wurde für einen Puffer zugeordnet.

Um zu überprüfen, ob der Zeiger zugewiesen wurde, überprüfen Sie den Rückgabewert von malloc():

fileBuff = malloc(size); 

if (fileBuff == 0) { 
    fprintf(stderr, "Error allocating %d bytes.\n", size); 
    abort(); 
} 
+0

'if (fileBuff == NULL) {' – Morpfh

+0

'if (0 == fileBuff ||! FileBuff) {' –

2

99 Entwickler jetzt antworten, dass Sie die Größe eines Zeigers einnehmen. Ich muss den Code nicht einmal ansehen.

+0

+1 Haha, ich dachte das Gleiche nach dem Lesen der Frage (aber ich * tat * Schau dir den Code an, um meine Hypothese zu bestätigen. ;-) –

+0

Dies ist der Testcode, ich versuche, das strlen (fileBuff) zu verwenden, aber es gibt 1 zurück. Sowohl sizeof() als auch strlen prüfen, ob der Dateipuffer mallokiert wurde. – panda

0

sizeof bei ausgewertet Zeit kompilieren, da Sie für sizeof von filebuf fragen, welche ein char* Compiler berechnet ist, dass es 4 Bytes (Da Größe des Zeigers 4 Bytes ist Ihre Plattform ub) und druckt sie. Die malloc, die Sie getan haben, hat nichts mit sizeof zu tun.

0

Neben den unsachgemäßen Gebrauch von sizeof() Sie 2 weitere Gedanken betrachten kann: kopieren, es ist

Wenn nur eine Datei: Versuchen Sie nicht, das Rad neu zu erfinden, und benutzen Sie einfach die system() Funktion und rufen Sie das dafür vorgesehene Betriebssystem auf (cp auf Unix, Kopie auf DOS/Windows).

Wenn es zu Trainingszwecken ist und Sie darauf bestehen, es selbst zu tun: Versuchen Sie nicht, die ganze Datei einzulesen und dann wieder auszu schreiben, aber lesen und schreiben Sie Stück für Stück. Die Verwendung zu großer Puffergrößen führt nur dazu, dass der CPU-Cache wertlos wird. Normalerweise Anpassung die Dateisystempuffergröße oder einen einfachen Bruchteils davon eine goot Chunkgröße wird, so dass der Pseudocode soll wie folgt aussehen:

open input file for reading 
open output file for writing 
as long as read from input file BUFSIZE bytes and read bytes > 0 
    do write read data to output file 
close input file 
close output file 

(und nicht vergessen für I/O-Fehler zu überprüfen nach jedem Aufruf eine E/a-Routine)

Und letzte Anmerkung: verwenden Sie keine fgets(), wenn Sie sicher wissen, es ist eine immer eine einfache Textdatei. Wenn Sie die fread()/fwrite() verwenden, sind Sie sicher, auch wenn es eine Binärdatei ist (und es ist auch schneller).

Verwandte Themen