2017-05-11 1 views
2

Ich habe bereits die Antwort auf eine ähnlichquestion gelesen, aber ich interessiere mich mehr für Stream-Pufferung beim Ausführen von E/A mit Dateien.setvbuf() - Puffergröße, wenn buf NULL ist

Wenn ich den folgenden Code

#include <stdio.h> 

int main(void) { 

    printf("%d\n", BUFSIZ); 

    FILE *fp = fopen("ekomi.txt", "wb"); 

    char array[2] = {'a', 'b'}; 
    fwrite(array, sizeof(char), 2, fp); 
    fclose(fp); 

    return 0; 
} 

druckt BUFSIZ = 8192 Soweit ich BUFSIZ verstehen sollte der Wert von glibc für die Größe des nach fopen standardmäßig erstellt Puffer verwendet werden (die Soweit ich weiß, sollte dies der gleiche sein wie das Aufrufen von setvbuf, das einen NULL-Zeiger auf den Parameter buf gibt). lief ich dieses Programm mit Massiv und die Ausgabe zeigt deutlich, dass die von glibc zugewiesenen Puffer

massif output

Die GNU-C-Bibliothek Dokumentation selbst nicht klar ist, über die Standardgröße des Puffers 4096 Bytes lang ist:

Wenn Sie einen Nullzeiger als Buf-Argument angeben, weist setvbuf einen Puffer selbst zu, der malloc verwendet. Dieser Puffer wird freigegeben, wenn Sie den Stream schließen.

Also meine Frage ist, wie glibc entscheidet, wie viel Speicher für den Puffer zu reservieren?

Antwort

0

Kurze Antwort: BUFSIZ ist die maximal zulässige Puffergröße, aber die im Malloc verwendete Größe wird vom Dateisystem blocksize angegeben.

Lange Antwort: Lassen Sie uns zurückverfolgen, was setvbuf macht, wenn wir einen NULL-Zeiger als buf übergeben.

https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/iosetvbuf.c#l60

_IO_DOALLOCATE (fp) 

https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/libioP.h#l237

#define _IO_DOALLOCATE(FP) JUMP0 (__doallocate, FP) 

Hier ruft eine "__doallocate" -Funktion zum FILE VTable im Zusammenhang mit dem JUMP0 Makro, und es wird _IO_file_doallocate Aufruf enden() hier definiert:

https://sourceware.org/git/?p=glibc.git;a=blob;f=libio/filedoalloc.c#l97

#if _IO_HAVE_ST_BLKSIZE 
    if (st.st_blksize > 0 && st.st_blksize < _IO_BUFSIZ) 
     size = st.st_blksize; 
#endif 

In der oben erwähnten Linie können Sie sehen, was ich in der kurzen Antwort wurde zu erwähnen. Es verwendet die stat64 struct (https://linux.die.net/man/2/stat64), um die Blockgröße des Dateisystems abzurufen und die Größe entsprechend zu setzen, wenn es kleiner als BUFSIZ ist.

+0

Danke, das macht Sinn. –