Does anyone know a reliable way to count the number of bytes written using standard C ( fwrite
) I / O in a complete disk situation?
I had a lot of problems getting this to work. The problem seems to be fwrite
buffered, and sometimes he thinks he wrote more bytes than the device can actually accept.
Using a small buffer of the same size as the blocks of the device, fwrite
let him know that he wrote a full buffer when this actually was not, so the number ended up being one more block than was correct. I fixed this error testing and only adding to the sum if there were no errors.
But then, with a large buffer, it fwrite
will write a partial buffer, and I will not count it. So I checked the partial record by adding and breaking out of the loop. The following program has been completed (reduced to MCVE):
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 8192
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, as well as 68k or 72k for free. I tried the buffer sizes 4k, 8k and 16k.
And the damn thing is still not working. When theres 72k for free and I use the 8k buffer, he writes 72k, then thinks he wrote another 4k and adds that.
I suppose I can just use a buffer size equal to the size of the block. But I'm not even sure that this will work reliably.
Does anyone know how to make it work in all cases? I think this can best just get around the buffering problem and use POSIX I / O instead ( open
and write
).
: nsilent22
:
setbuf(stdout, NULL);
...
while ((written = fwrite(buf, 1, BUF_SIZE, stdout)) > 0)
ct += written;