有没有可靠的方法使用C标准I/O(
该设备有4k块,剩余空间为68k或72k。我尝试了4k、8k和16k的缓冲区大小。
但该死的东西仍然不起作用。当剩余空间为72k且使用8k缓冲区时,它写入了72k,然后认为又写入了4k并添加了它。
我想我可以只使用与块大小相等的缓冲区大小。但我甚至不确定这会可靠地工作。
有人知道如何使其在所有情况下都能正常工作吗?我想最好是完全绕过缓冲问题,改用POSIX I/O(open和write)。
编辑:nsilent22的建议正确地解决了问题,并将循环减少到了两行:
fwrite
)在磁盘已满的情况下计算实际写入的字节数?
我一直很苦恼如何让它正常工作。问题似乎是fwrite
被缓存,有时会认为它写入了比设备实际可以接受的更多的字节。
使用一个小缓冲区,与设备块大小相同,当实际写入不足一个缓冲区时,fwrite
将报告它已经写满了一个缓冲区,因此计数结束时会比正确值多一个块。我通过测试错误并且只在没有错误时增加总数来解决这个问题。
但是,使用较大的缓冲区,fwrite
会写入部分缓冲区,这样我就无法计算。所以我检查了部分写入,并加上了中断循环的代码。最终得到了以下程序(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;
}
该设备有4k块,剩余空间为68k或72k。我尝试了4k、8k和16k的缓冲区大小。
但该死的东西仍然不起作用。当剩余空间为72k且使用8k缓冲区时,它写入了72k,然后认为又写入了4k并添加了它。
我想我可以只使用与块大小相等的缓冲区大小。但我甚至不确定这会可靠地工作。
有人知道如何使其在所有情况下都能正常工作吗?我想最好是完全绕过缓冲问题,改用POSIX I/O(open和write)。
编辑:nsilent22的建议正确地解决了问题,并将循环减少到了两行:
setbuf(stdout, NULL);
...
while ((written = fwrite(buf, 1, BUF_SIZE, stdout)) > 0)
ct += written;
setbuf
和NULL一起是一个选项吗? - nsilent22