مؤشر نهاية FILE* لا يساوي حجم البيانات المكتوبة

StackOverflow https://stackoverflow.com/questions/145006

  •  02-07-2019
  •  | 
  •  

سؤال

بكل بساطة، لدي مقتطف الشفرة التالي:

FILE* test = fopen("C:\\core.u", "w");
printf("Filepointer at: %d\n", ftell(test));
fwrite(data, size, 1, test);
printf("Written: %d bytes.\n", size);
fseek(test, 0, SEEK_END);
printf("Filepointer is now at %d.\n", ftell(test));
fclose(test);

ويخرج:

Filepointer at: 0
Written: 73105 bytes.
Filepointer is now at 74160.

لماذا هذا؟لماذا لا يتطابق عدد البايتات المكتوبة مع مؤشر الملف؟

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

المحلول

نظرًا لأنك تفتح الملف في الوضع النصي، فسيتم تحويل علامات نهاية السطر، مثل LF، إلى CR/LF.

من المحتمل أن يكون هذا إذا كنت تعمل على نظام التشغيل Windows (وربما تكون كذلك، نظرًا لأن اسم الملف الخاص بك يبدأ بـ "c:\").

إذا قمت بفتح الملف في "wb" الوضع، أظن أنك ستجد الأرقام متطابقة:

FILE* test = fopen("C:\\core.u", "wb");

معيار C99 يقول هذا 7.19.5.3 The fopen function:

يشير وضع الوسيطة إلى سلسلة.إذا كانت السلسلة واحدة مما يلي ، فإن الملف مفتوح في الوضع المشار إليه.وإلا فإن السلوك غير محدد.

r فتح ملف نصي للقراءة
w اقتطاع إلى طول صفر أو إنشاء ملف نصي للكتابة
a ألحق؛فتح أو إنشاء ملف نصي للكتابة في نهاية الملف
rb فتح الملف الثنائي للقراءة
wb اقتطاع إلى طول صفر أو إنشاء ملف ثنائي للكتابة
ab ألحق؛فتح أو إنشاء ملف ثنائي للكتابة في نهاية الملف
r+ فتح ملف نصي للتحديث (القراءة والكتابة)
w+ اقتطاع إلى طول صفر أو إنشاء ملف نصي للتحديث
a+ ألحق؛فتح أو إنشاء ملف نصي للتحديث والكتابة في نهاية الملف
r+b أو rb+ فتح الملف الثنائي للتحديث (القراءة والكتابة)
w+b أو wb+ اقتطاع إلى طول صفر أو إنشاء ملف ثنائي للتحديث
a+b أو ab+ ألحق؛فتح أو إنشاء ملف ثنائي للتحديث والكتابة في نهاية الملف

يمكنك أن ترى أنهم يميزون بين w و wb.لا أعتقد أن التنفيذ هو مطلوب للتعامل مع الاثنين بشكل مختلف ولكن عادةً ما يكون استخدام الوضع الثنائي للبيانات الثنائية أكثر أمانًا.

نصائح أخرى

ماذا يعود fwrite؟عادة يجب أن تكون قيمة الإرجاع عدد البايتات المكتوبة.أيضًا، ما الذي يجيب عليه ftell() مباشرة قبل fseek؟

قد يكون من المفيد معرفة نظام التشغيل وإصدار مترجم C ومكتبة C.

مؤشر الملف هو ملف تعريف الارتباط.ليس لها قيمة.الشيء الوحيد الذي يمكنك استخدامه من أجله هو البحث عن نفس المكان في الملف.لست متأكدًا حتى مما إذا كانت ISO C تضمن أن ftell تُرجع قيمًا متزايدة.إذا كنت لا تصدق ذلك، يرجى إلقاء نظرة على أوضاع البحث () المختلفة.إنها موجودة على وجه التحديد لأن الموضع ليس عبارة عن إزاحة بايت بسيطة.

لا يقوم Windows في الواقع بكتابة جميع البيانات إلى الملف بدون تدفق وربما fsync.ربما هذا السبب

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