c - Reliably counting bytes written by fwrite when disk is full -
does know reliable way count how many bytes have been written, using c standard i/o (fwrite), in disk-full situation?
i’ve had lot of trouble getting work. problem seems fwrite buffered, , thinks has written more bytes device can accept.
using small buffer, same size device blocks, fwrite report had written full buffer when had not, count ended being 1 block more correct. fixed testing error , adding total if there no error.
but then, larger buffer, fwrite write partial buffer, , fail count that. checked partial write, adding , breaking out of loop. ended following program (reduced mcve):
#include <stdio.h> #include <string.h> //#define buf_size 4096 #define buf_size 8192 //#define buf_size 16384 int main(void) { unsigned long long ct = 0; size_t written; unsigned char *buf; buf = malloc(buf_size); memset(buf, 0xff, buf_size); while (1) { written = fwrite(buf, 1, buf_size, stdout); if (written < buf_size) { ct += written; break; } fflush(stdout); if (ferror(stdout)) break; ct += written; } fprintf(stderr, "%llu bytes written\n", ct); return 0; } the device has 4k blocks, , either 68k or 72k free. tried buffer sizes of 4k, 8k, , 16k.
and darned thing still doesn’t work. when there’s 72k free , use 8k buffer, writes 72k, thinks wrote 4k , adds that.
i suppose use buffer size that’s equal block size. i’m not sure work reliably.
does know how make work in cases? i’m thinking might best bypass buffering issue entirely , use posix i/o instead (open , write).
edit: nsilent22’s suggestion worked correctly , reduced loop 2 lines:
setbuf(stdout, null); ... while ((written = fwrite(buf, 1, buf_size, stdout)) > 0) ct += written;
consider using setbuf function null parameter buffer. turn off stream buffering.
Comments
Post a Comment