【问题标题】:Why does write continuously leave 4K bytes in the buffer?为什么写入连续在缓冲区中留下 4K 字节?
【发布时间】:2020-07-23 13:58:15
【问题描述】:

我基本上有以下代码:

int fileWrite(int file, void * pBuffer, size_t size)
{
    size_t bytesWritten = (size_t)write( file, pBuffer, size ) ;
    if (bytesWritten != size)
    {
       return -1;
    }
    return 0;
}

如果大小为 1GB,它可以工作,但是当大小为 ~2GB 时,它会始终保持 4K 字节。我可以通过将写入包装在一个循环中并将缓冲区向上移动来解决此问题,但我很好奇它为什么总是失败。

例如,如果大小为 2147483648,则只写入 2147479552,留下 4096 未写入。为什么会发生这种情况?总是将 write 包装在一个循环中是否正确?

【问题讨论】:

  • 您是否在 32 位模式下运行它? 2gig 是最大的 32 位数字。
  • write 一次消耗多少数据的规则取决于file 是什么类型的数据接收器(例如“常规”文件、管道、流套接字、数据报套接字…… )。你能说得更具体点吗?
  • 等等,你是不是想同时write整个文件?通常的方法是一次将数据流传输一个缓冲区大小,直到您写完所有内容。
  • @Luaan 如果您已经拥有所有数据,我看不出有什么错误一次性写出来,但正如这个问题和答案所示,write() 没有不必全部写完(也适用于小缓冲区)
  • “我可以通过将 write 包装在一个循环中来解决这个问题”,无论SSIZE_MAX 限制如何,您都需要这样做。 write() 规范说它没有义务写入完整的缓冲区,即使它几乎总是这样做。问题中的无循环代码是一个错误。

标签: c linux system-calls


【解决方案1】:

你可以在man 2 write找到答案:

如果这个数字小于字节数不是错误 要求;这可能发生,例如,因为磁盘设备是 填满。


来自write() 手册页的描述:

ssize_t write(int fd, const void *buf, size_t count);

根据POSIX.1,如果count大于SSIZE_MAX,则结果 是实现定义的; Linux 上的上限请参见 NOTES。

注意事项

在 Linux 上,write()(和类似的系统调用)最多会传输 0x7ffff000 (2,147,479,552) 字节,返回字节数 实际转移。 (这在 32 位和 64 位上都是如此 系统。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-13
    • 2019-02-20
    相关资源
    最近更新 更多