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

问题描述 投票:8回答:4

根据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指出:

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. 

所以,也许我收到中断读取的信号,因此由于错误或由于认为读取了零字节而返回的值为零?

根据read(2)的手册页,仅当到达EOF时,它才返回零。但是,这似乎是不正确的,并且有时它可能返回零,可能是因为文件尚未准备好...

c++ linux eof
4个回答
5
投票

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


3
投票

我能想到的read()唯一返回0的其他情况是,如果您将nbytes传递为0;如果您将某物或其他尺寸作为参数传递,有时可能会发生这种情况。难道这就是现在发生的事情吗?


1
投票

想通了!我有未初始化的内存读取(UMR),并且错误地寻找到文​​件的末尾。


0
投票

我已经处理了很多次。由于应用程序不知道fd是否已附加到平面文件,网络的套接字,管道等,因此某些进程可能会发送优先级为零或其他优先级的零长度消息,并触发此消息。我拭目以待,看看EOF是否粘着:

© www.soinside.com 2019 - 2024. All rights reserved.