De acuerdo con la página man para lectura (2), solo devuelve cero cuando se alcanza EOF.¿Puede leer (2) devolver cero cuando no está en EOF?
Sin embargo, parece que esto es incorrecto y que a veces puede regresar a cero, tal vez porque el archivo no está listo para ser leído todavía? ¿Debo llamar a select() para ver si está listo antes de leer un archivo del disco?
Tenga en cuenta que nBytes es: 1445888
un código de ejemplo:
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;
}
}
La salida lee (cuando se produce un error con leer ningún dato):
available: 1445888 availableIn: 0 bufferSize: 1445888 got: 0
Esto se está ejecutando en CentOS4 32 bit como una máquina virtual utilizando VMware Server 1.0.10. El sistema de archivos que se lee es local para la máquina virtual. La máquina host es Windows Server 2008 de 32 bits.
El uname -a dice:
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
noto que el enlace que figura a continuación http://opengroup.org/onlinepubs/007908775/xsh/read.html estados:
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.
Por lo tanto, tal vez estoy recibiendo una señal de interrupción de la lectura y por lo tanto el valor devuelto es cero debido a un error o cree que se leyeron cero bytes?
No puedo pensar por qué devolvería 0 cuando no esté en EOF. ¿Puedes dar un ejemplo específico de cuándo sucede esto? –
Ocurre en aproximadamente uno de cada 50,000 intentos idénticos. – WilliamKF
No es necesario seleccionar() en el descriptor de archivo. (¿Por qué demonios en el 3er milenio aún usas select() y no el sondeo() ??) Los archivos siempre son legibles; no son sockets ni dispositivos, no pueden bloquearse.Un poco más de información sobre el sistema (distribución, versión del kernel, sistema de archivos utilizado) podría ser útil. – Dummy00001