当不在 EOF 时 read(2) 可以返回零吗?

2023-12-29

根据 read(2) 的手册页,当达到 EOF 时它仅返回零。

但是,这似乎是不正确的,有时可能会返回零,也许是因为文件尚未准备好读取?在从磁盘读取文件之前,我应该调用 select() 来查看它是否准备好吗?

请注意,nBytes 为:1,445,888

一些示例代码:

fd_set readFdSet;
timeval timeOutTv;

timeOutTv.tv_sec = 0;
timeOutTv.tv_usec = 0;

// Let's see if we'll block on the read.
FD_ZERO(&readFdSet);
FD_SET(fd, &readFdSet);

int selectReturn = ::select(fd + 1, &readFdSet, NULL, NULL, &timeOutTv);

if (selectReturn == 0) {
  // There is still more to read.
  return false; // But return early.
} else if (selectReturn < 0) {
  clog << "Error: select failure: " << strerror(errno) << endl;
  abort();
} else {
  assert(FD_ISSET(fd, &readFdSet));

  try {
    const int bufferSizeAvailable = _bufferSize - _availableIn;

    if (_availableIn) {
      assert(_availableIn <= _bufferSize);

      memmove(_buffer, _buffer + bufferSizeAvailable, _availableIn);
    }

    ssize_t got = ::read(fd, _buffer + _availableIn, bufferSizeAvailable);

    clog << " available: " << bufferSizeAvailable << " availableIn: "
         << _availableIn << " bufferSize: " << _bufferSize << " got "
         << got << endl;

    return got == 0;
  } catch (Err &err) {
    err.append("During load from file.");
    throw;
  }
}

输出读取(当失败且没有读取数据时):

available: 1445888 availableIn: 0 bufferSize: 1445888 got: 0

这是使用 VMware Server 1.0.10 作为虚拟机在 centos4 32 位上运行。正在读取的文件系统是虚拟机本地的。主机是windows server 2008 32位。

uname -a 说:

Linux q-centos4x32 2.6.9-89.0.25.ELsmp #1 SMP Thu May 6 12:28:03 EDT 2010 i686 i686 i386 GNU/Linux

我注意到链接http://opengroup.org/onlinepubs/007908775/xsh/read.html http://opengroup.org/onlinepubs/007908775/xsh/read.html给出如下状态:

The value returned may be less than nbyte if the number of bytes left in the file is less than nbyte, if the read() request was interrupted by a signal...

If a read() is interrupted by a signal before it reads any data, it will return -1 with errno set to [EINTR].

If a read() is interrupted by a signal after it has successfully read some data, it will return the number of bytes read. 

那么,也许我收到一个中断读取的信号,因此返回的值为零,因为要么是错误,要么是它认为读取了零字节?


经过一些研究,实际上在某些情况下它会返回 0,你可能不认为这是“EOF”。

有关详细信息,请参阅 read() 的 POSIX 定义:https://pubs.opengroup.org/onlinepubs/009604599/functions/read.html https://pubs.opengroup.org/onlinepubs/009604599/functions/read.html

一些值得注意的问题是,如果您要求它读取 0 个字节 - 仔细检查您是否意外地将 0 传递给它 - 并读取文件“写入”部分的末尾(您实际上可以在末尾处查找)如果您在那里写入,则会用零“扩展”文件,但在您这样做之前,“EOF”仍然位于已写入部分的末尾)。

我最好的猜测是你在某个地方遇到了时间问题。您需要问的一些问题是“这些文件是如何写入的?”和“当我尝试读取它们时,我确定它们不是零长度吗?”。对于第二个,您可以尝试在读取文件之前运行 stat() 以查看其当前大小。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当不在 EOF 时 read(2) 可以返回零吗? 的相关文章

随机推荐