Reliability of counting bytes written by fwrite when the disk is full

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 fwritebuffered, 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 fwritewill 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 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, 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 ( openand write).


: nsilent22 :

    setbuf(stdout, NULL);
    ...
    while ((written = fwrite(buf, 1, BUF_SIZE, stdout)) > 0)
        ct += written;
+4
2

setbuf NULL . .

+1

Im , POSIX I/O (open write).

! . fread , , , , , fflush() , . , .

fclose() , ( ) , , / Posix .

, , .

, . ​​ ... Posix API , 2, , . , .

, 32 , 2G 4G. - . , .

+1

Source: https://habr.com/ru/post/1627568/


All Articles