متى لا يمكن لـ DataInputStream.skipBytes(n) تخطي n بايت؟
سؤال
ال وثائق الشمس لـ DataInput.skipBytes ينص على أنه "يقوم بمحاولة تخطي n بايت من البيانات من دفق الإدخال، مع تجاهل البايتات التي تم تخطيها.ومع ذلك، قد يتم تخطي عدد أصغر من البايتات، ربما صفر.قد ينتج هذا عن أي عدد من الشروط؛إن الوصول إلى نهاية الملف قبل تخطي n بايت هو احتمال واحد فقط."
بخلاف الوصول إلى نهاية الملف، لماذا
skipBytes()
لا تخطي العدد الصحيح من البايتات؟(الDataInputStream
أنا أستخدم إما أن يكون التفافFileInputStream
أو أPipedInputStream
.)إذا كنت أرغب بالتأكيد في تخطي n بايت ورمي
EOFException
إذا دفعني هذا إلى الانتقال إلى نهاية الملف، فهل يجب أن أستخدمهreadFully()
وتجاهل مجموعة البايت الناتجة؟او هل هناك طريقه افضل؟
المحلول
1) قد لا يكون هناك الكثير من البيانات المتاحة للقراءة (ربما لم يرسل الطرف الآخر من الأنبوب هذا القدر من البيانات بعد)، وقد تكون فئة التنفيذ غير محظورة (أي.سيعيد فقط ما يستطيع، بدلاً من انتظار ما يكفي من البيانات لتلبية الطلب).
لا أعرف ما إذا كانت أي تطبيقات تتصرف بهذه الطريقة بالفعل، ولكن الواجهة مصممة للسماح بذلك.
هناك خيار آخر وهو ببساطة أن يتم إغلاق الملف جزئيًا خلال عملية القراءة.
2) إما readFully() (والذي سينتظر دائمًا إدخالاً كافيًا وإلا سيفشل) أو استدعاء SkiBytes() في حلقة.أعتقد أن الأول ربما يكون أفضل، إلا إذا كانت المجموعة واسعة حقًا.
نصائح أخرى
لقد واجهت هذه المشكلة اليوم.لقد كان يقرأ اتصال الشبكة على جهاز افتراضي، لذا أتصور أنه قد يكون هناك عدد من الأسباب لحدوث ذلك.لقد قمت بحلها ببساطة عن طريق إجبار دفق الإدخال على تخطي البايتات حتى يتخطى عدد البايتات التي أردتها:
int byteOffsetX = someNumber; //n bytes to skip
int nSkipped = 0;
nSkipped = in.skipBytes(byteOffsetX);
while (nSkipped < byteOffsetX) {
nSkipped = nSkipped + in.skipBytes(byteOffsetX - nSkipped);
}
لقد نشر جوش بلوخ هذا مؤخرًا.ومن الثابت أن InputStream.read ليس مضمونًا قراءة أكبر عدد ممكن من البايتات.ومع ذلك، فإنه لا معنى له على الإطلاق كطريقة API.من المحتمل أيضًا أن يحتوي InputStream على قراءة كاملة.
اتضح أن readFully() يضيف المزيد من الأداء العام مما كنت على استعداد لتحمله.
وفي النهاية تنازلت:أقوم باستدعاء SkiBytes() مرة واحدة، وإذا أدى ذلك إلى إرجاع عدد أقل من العدد الصحيح للبايتات، فإنني أتصل بـ readFully() للبايتات المتبقية.