ما هو الأساس المنطقي لfread / fwrite حجم أخذ واعتباره الحجج؟

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

  •  08-07-2019
  •  | 
  •  

سؤال

وكان لدينا نقاش هنا في العمل بشأن لماذا fread fwrite وتأخذ حجم لكل الأعضاء والعد وإرجاع عدد من أعضاء قراءة / مكتوبة بدلا من مجرد أخذ العازلة والحجم. استخدام الوحيد لذلك يمكننا أن نخرج هو إذا كنت ترغب في قراءة / كتابة مجموعة من البنيات التي ليست قسمة محاذاة منصة، وبالتالي يكون قد مبطن ولكن هذا لا يمكن أن تكون مشتركة وذلك لتبرير هذا الاختيار في التصميم.

من FREAD (3) :

<اقتباس فقرة>   

ووfread () وظيفة يقرأ عناصر nmemb من البيانات، كل حجم بايت،   من تيار المشار إليه بواسطة تيار، وتخزينها في مكان معين   بواسطة PTR.

     

ووfwrite () وظيفة يكتب nmemb عناصر البيانات، كل حجم بايت   وأشار الطويل، إلى تيار من قبل تيار، الحصول عليها من الموقع   التي قدمها PTR.

     

وfread () و fwrite () إرجاع عدد من العناصر قراءة أو كتابة بنجاح   (أي، وليس عدد الأحرف). إذا حدث خطأ، أو   نهاية ملف يتم التوصل قيمة الإرجاع هي عدد البند القصير (أو صفر).

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

المحلول

وأنها تقوم على كيفية تنفيذ fread .

وواحدة UNIX مواصفات يقول

<اقتباس فقرة>   

لكل كائن، يجب أن تكون المكالمات حجم   التي أدخلت على وظيفة fgetc () و   تخزين النتائج، وفقا للترتيب القراءة، في   مجموعة من الحرف غير الموقعة بالضبط   تتراكب الكائن.

fgetc أيضا هذه المذكرة:

<اقتباس فقرة>   

ومنذ fgetc () يعمل على بايت،   قراءة حرف تتكون من   بايت متعددة (أو "متعدد بايت   شخصية ") قد تتطلب مكالمات متعددة   لfgetc ().

وبطبيعة الحال، وهذا يسبق المحارف متغير بايت نزوة مثل UTF-8.

ويشير SUS أن هذا يؤخذ في الواقع من وثائق ISO C.

نصائح أخرى

والفرق في fread (BUF، 1000، 1، تيار) وfread (BUF، 1، 1000، تيار) هو أنه في الحالة الأولى تحصل فقط قطعة واحدة من 1000 بايت أو nuthin، إذا كان الملف أصغر وفي الحالة الثانية تحصل على كل شيء في ملف أقل من وتصل إلى 1000 بايت.

وهذا هو تكهنات نقية، ولكن مرة أخرى في أيام (بعض لا تزال موجودة) وكانت العديد من أنظمة الملفات لا تيارات بايت بسيطة على القرص الصلب.

و

وأنظمة الملفات كثيرة سجل استنادا، وبالتالي لتلبية هذه أنظمة الملفات بطريقة فعالة، سيكون لديك لتحديد عدد وحدات ( "السجلات")، مما يسمح fwrite / fread بالعمل على التخزين كما السجلات، وليس فقط تيارات بايت.

وهنا، اسمحوا لي أن إصلاح تلك الوظائف:

size_t fread_buf( void* ptr, size_t size, FILE* stream)
{
    return fread( ptr, 1, size, stream);
}


size_t fwrite_buf( void const* ptr, size_t size, FILE* stream)
{
    return fwrite( ptr, 1, size, stream);
}

وأما عن الأساس المنطقي للمعلمات لfread() / fwrite()، لقد فقدت نسختي من K & R منذ فترة طويلة لا أستطيع تخمين فقط. أعتقد أن الجواب المحتمل هو أن كيرنيغان وريتشي قد يعتقد أن أداء ثنائي I / O سيتم القيام به أكثر بطبيعة الحال على صفائف من الأشياء ببساطة. أيضا، فقد كان يظن أن كتلة I / O يكون أسرع / أسهل في التنفيذ أو أيا كان في بعض أبنية.

وعلى الرغم من يحدد مستوى C التي fread() وfwrite() ستنفذ من حيث fgetc() وfputc()، تذكر أن المعيار جاء إلى حيز الوجود بعد فترة طويلة تم تعريف C التي كتبها K & R وأن الأمور المحددة في المعيار ربما لم تكن في النص الأصلي المصممين الأفكار. حتى انه من الممكن أن الأمور قد قال في K & R في "وC لغة البرمجة" قد لا يكون هو نفسه عندما تم لأول مرة يجري تصميم اللغة.

وأخيرا، وهنا ما لديها P.J. Plauger ليقوله عن fread() في "مكتبة قياسي C":

<اقتباس فقرة>   

وإذا كان size (الثاني) حجة أكبر من واحد، لا يمكنك تحديد   إذا كانت وظيفة أيضا قراءة ما يصل الى size - 1 أحرف إضافية تتجاوز ما يفيد ذلك.   وكقاعدة عامة، كنت أفضل حالا استدعاء الدالة كما fread(buf, 1, size * n, stream); بدلا من   fread(buf, size, n, stream);

وBascially، يقوله اجهة fread() هي مكسورة. لfwrite() أنه يلاحظ أن "أخطاء الكتابة نادرة عموما، لذلك هذا ليس عيبا رئيسيا" - بيان وأود أن لا نتفق مع

ويرجح انه يعود الى الطريقة التي ملف I / O تم تنفيذه. (مرة في اليوم) وربما كان أسرع في الكتابة / القراءة الملفات في كتل ثم لكتابة كل شيء في وقت واحد.

وأعتقد أنه لأن C تفتقر إلى وظيفة الحمولة الزائدة. إذا كان هناك بعض، من شأنه أن يكون حجم زائدة عن الحاجة. ولكن في C لا يمكنك تحديد حجم عنصر صفيف، لديك لتحديد واحد.

والنظر في هذا:

int intArray[10];
fwrite(intArray, sizeof(int), 10, fd);

إذا fwrite قبلت عدد بايت، يمكن أن تكتب ما يلي:

int intArray[10];
fwrite(intArray, sizeof(int)*10, fd);

ولكن هو مجرد فعالة. سيكون لديك sizeof (دولي) مرات أكثر استدعاءات النظام.

وثمة نقطة أخرى يجب taked من الاعتبار هو أنك عادة لا تريد أن يكتب جزءا من عنصر صفيف إلى ملف. تريد صحيحا كله أو لا شيء. fwrite إرجاع عدد من العناصر كتابة بنجاح. حتى إذا كنت يكتشف أن فقط 2 بايت منخفضة من عنصر هو مكتوب ماذا كنت ستفعل؟

في بعض الأنظمة (بسبب المحاذاة) لا يمكنك الوصول إلى بايت واحد من عدد صحيح بدون إنشاء نسخة والتحول.

وبعد الحجج منفصلة لحجم وعدد يمكن أن يكون من المفيد على تنفيذ التي يمكن أن تجنب قراءة أي سجلات جزئية. إذا كان للمرء أن استخدام واحد بايت يقرأ من شيء مثل الأنابيب، وحتى لو تم استخدام البيانات شكل ثابت، يمكن لأحد أن يكون واحد لإتاحة إمكانية الحصول على سجل مقسمة على اثنين من يقرأ. إذا يمكن بدلا من ذلك على سبيل المثال تطلب غير مؤمن قراءة ما يصل إلى 40 سجلات 10 بايت لكل عندما يكون هناك 293 بايت متوفرة، ولها بايت عودة النظام 290 (29 سجلات كاملة) مع ترك 3 بايت على استعداد لقراءة المقبلة، التي من شأنها أن تكون أكثر ملاءمة.

وأنا لا أعرف إلى أي مدى تطبيقات fread يمكن التعامل مع هذه الدلالات، ولكنها يمكن أن تكون بالتأكيد مفيد على التطبيقات التي يمكن أن نعد لتقديم الدعم لهم.

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