当前位置:  开发笔记 > 编程语言 > 正文

读取(2)不在EOF时返回零?

如何解决《读取(2)不在EOF时返回零?》经验,为你挑选了1个好方法。

根据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. 

所以,也许我得到一个信号中断读取,因此返回的值是零因为一个错误或它认为零字节被读取?



1> Nicholas Kni..:

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

有关具体细节,请参见read()的POSIX定义:http : //opengroup.org/onlinepubs/007908775/xsh/read.html

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

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


@WilliamKF:真的很奇怪。听起来好像是内核/文件系统错误。我什至不知道隔离这种情况的最佳方法。您可能需要点击linux-kernel邮件列表或IRC频道。可能值得尝试的一件事是查看它是否发生在不同类型的文件系统上。
推荐阅读
mobiledu2402851377
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有