سؤال

وفقًا لصفحة Man for 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

يتم تشغيل هذا على CentOS4 32 بت كآلة افتراضية باستخدام VMware Server 1.0.10. نظام الملفات الذي يجري قراءته محلي للجهاز الظاهري. الجهاز المضيف هو 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. 

لذلك ، ربما أحصل على إشارة تقاطع القراءة ، وبالتالي فإن القيمة التي تم إرجاعها هي صفر بسبب وجود خطأ أو تعتقد أنه تم قراءة بايت صفر؟

هل كانت مفيدة؟

المحلول 3

اكتشفه! كان لدي قراءة ذاكرة غير مهيأة (UMR) وكنت تبحث بشكل غير صحيح إلى نهاية الملف.

نصائح أخرى

بعد بعض الأبحاث ، هناك بالفعل بعض الظروف التي ستعود فيها 0 والتي قد لا تفكر فيها على أنها "EOF".

للاطلاع على التفاصيل الجريئة ، راجع تعريف Posix لـ read (): http://opengroup.org/onlinepubs/007908775/xsh/read.html

بعضها البارز هو إذا طلبت من قراءة 0 بايت - تحقق مزدوجًا أنك لا تمر بطريق الخطأ 0 - وقراءة نهاية الجزء "المكتوب" من الملف (يمكنك بالفعل البحث عن النهاية من الملف ، الذي "يمتد" الملف بالأصفار إذا كتبت هناك ، ولكن حتى تفعل ، لا يزال "EOF" في نهاية الجزء المكتوب بالفعل).

أفضل تخميني هو أنك تدخل في مشكلة التوقيت في مكان ما. بعض الأسئلة التي تحتاج إلى طرحها هي "كيف يتم كتابة هذه الملفات؟" و "هل أنا متأكد من أنهم ليسوا بطولًا عندما أحاول قراءتها؟". بالنسبة للثاني ، يمكنك محاولة تشغيل STAT () على الملف قبل قراءته لمعرفة حجمها الحالي.

الحالة الأخرى الوحيدة التي يمكنني التفكير فيها في القراءة () إرجاع 0 هي إذا مررت في nbytes كـ 0 ؛ في بعض الأحيان يمكن أن يحدث ذلك إذا كنت تمر بحجم شيء أو آخر كمعلمة. هل يمكن أن يكون هذا ما يحدث الآن؟

إذا لم يكن الملف جاهزًا للقراءة ، فإن ما يجب أن يحدث هو قراءة الإرجاع -1 ويتم تعيين Errno على Eagain.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top