هل هناك أي سبب عادي لاستخدام Open () بدلا من FOPEN ()؟

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

  •  23-08-2019
  •  | 
  •  

سؤال

أقوم بمشروع صغير في ج بعد فترة طويلة بعيدا عن ذلك. تحدث هذه لتضمين بعض معالجة الملفات. لقد لاحظت في وثائق مختلفة أن هناك وظائف تعود FILE * مقابض وغيرها من أي ظهور (عدد صحيح صغير). تقدم كلتا المجموعتين من الوظائف نفس الخدمات الأساسية التي أحتاج إليها، لذلك لا يهم حقا استخدامها.

لكنني فضولي حول حكمة المجموعة: هل من الأفضل استخدامها fopen() والأصدقاء، أو open() والأصدقاء؟

يحرر نظرا لأن شخصا ما ذكر مؤشرا مؤقتا مقابل الأجهزة والوصول إليها، أود أن أضيف أن جزءا من هذا المشروع الصغير سيكون كتابة برنامج تشغيل نظام ملفات للمستخدمين ضمن الصمامات. لذلك يمكن الوصول إلى مستوى الملف بسهولة على جهاز (على سبيل المثال CDROM أو محرك الأقراص SCSI) كما في "ملف" (أي صورة).

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

المحلول

الاعتراض الذي "FOPEN" محمول و "فتح" ليس هو وهمية.

FOPEN جزء من LIBC، فتح مكالمة نظام Posix.

كلها محمولة مثل المكان الذي يأتون منه.

I / O إلى ملفات fopen'ed هو (يجب أن تفترض أنه قد يكون، والأغراض العملية، هو) مخزنة من قبل libc، واصطفات الملفات المفتوحة () ED ليست مخزنة من قبل libc (قد تكون كذلك، وعادة ما تكون عادة مخزنة في نظام الملفات - ولكن ليس كل ما تفتحه () هو ملف على نظام ملفات.

ما هي نقطة fopen'ing، على سبيل المثال، عقدة جهاز مثل / dev / sg0، أو / dev / tty0 ... ماذا ستفعل؟ أنت ستفعل Ioctl على ملف *؟ حظا جيدا في ذلك.

ربما تريد فتح بعض الأعلام مثل O_Direct - لا معنى له مع FOPEN ().

نصائح أخرى

من الأفضل استخدام Open () إذا كنت تلتصقا لأنظمة مثل UNIX وقد ترغب في:

  • لديك المزيد من التحكم في الحبيبات الجميلة على أجزاء إذن UNIX على إنشاء الملفات.
  • استخدم الوظائف ذات المستوى الأدنى مثل القراءة / الكتابة / mmap بدلا من وظائف دفق I / O المخزونة C.
  • استخدم جدولة IO واصف الملفات (FD) المستندات (الاستطلاع، حدد، وما إلى ذلك)، يمكنك بالطبع الحصول على FD من ملف * باستخدام Fileno ()، ولكن يجب أن تؤخذ الرعاية لعدم مزج الملفات القائمة على الوظائف القائمة على الوظائف المستندة إلى FD وبعد
  • افتح أي جهاز خاص (وليس ملف منتظم)

من الأفضل استخدام FOPEN / FRWWRITE / FWWRITE للحصول على أقصى قدر من إمكانية النقل، لأن هذه هي وظائف C القياسية، والوظائف التي ذكرتها أعلاه ليست كذلك.

يعمل FOPEN على مستوى أعلى من Open .... FOPEN يعيدك مؤشر إلى تيار الملفات مما يشبه تجريد الدفق الذي تقرأه في C ++

افتح إرجاع لك واصف الملفات لفتح الملف ... إنه لا يوفر عليك تجريد دفق وأنت مسؤول عن التعامل مع البتات والايت بايت ... هذا على مستوى أقل بالمقارنة مع FOPEN

تيارات Stdio مخزنة مؤقتا، في حين أن ملفات الملفات المفتوحة () ليست كذلك. يعتمد على ما تحتاجه. يمكنك أيضا إنشاء واحد من الآخر:

إرجاع Int Fileno (File * Stream) واصف الملف للحصول على ملف *، ملف * FDOPEN (Int Fildes، Const Char * Mode) إنشاء ملف * من واصف الملفات.

توخي الحذر عند التعامل مع INTMIXING مؤقتا وغير مؤجش مؤقتا، حيث ستفقد ما هو في المخزن المؤقت الخاص بك عندما لا تدفعه مع Fflush ().

نعم. عندما تحتاج إلى مقبض منخفض المستوى.

على أنظمة التشغيل UNIX، يمكنك عموما تبادل مقابض الملفات والمقابس.

أيضا، تصنع مقابض منخفضة المستوى لتحسين توافق ABI من مؤشرات الملفات.

عادة، يجب أن تفضل استخدام المكتبة القياسية (FOPEN). ومع ذلك، هناك مناسبات حيث ستحتاج إلى استخدام فتح مباشرة.

مثال واحد يتبادر إلى الذهن هو العمل حول خطأ في إصدار أقدم من سولاريس الذي جعل Fopen فشل بعد 256 ملفات مفتوحة. كان هذا لأنهم يستخدمون char غير موقعة لحقل FD في تنفيذ ملفات الهيكل بدلا من int. لكن هذه كانت حالة محددة للغاية.

اقرأ() & اكتب() استخدم I / O غير معروف. فيفاد: واصف ملف صحيح)

fraeb () & fwrite () استخدام المخزن المؤقت I / O. فيملف* مؤشر الهيكل)

البيانات الثنائية مكتوبة إلى أنبوب مع اكتب() ربما لا تكون قادرة على قراءة البيانات الثنائية مع fraeb (), ، بسبب محاذاة البايت، والأحجام المتغيرة، إلخ. انها تبادل لاطلاق النار حماقة.

يستخدم معظم رمز برنامج تشغيل الجهاز منخفض المستوى مكالمات I / O غير مقيدة.

يستخدم معظم مستوى التطبيق I / O مخزن مؤقتا.

استخدام ملف* ووظائفها المرتبطة بها على ما يرام على أساس الجهاز بواسطة الجهاز: ولكن يتم فقد قابلية النقل على بنية أخرى في قراءة البيانات الثنائية وكتابةها. FWRite () مخزنة مؤقتا I / O ويمكن أن يؤدي إلى نتائج غير موثوق بها إذا كتبت بنية 64 بت وتشغيلها على 32 بت؛ أو (ويندوز / لينكس). معظم OSS لها وحدات ماكرو التوافق ضمن الكود الخاص بها لمنع هذا.

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

<stdio.h>  // mostly FILE*  some fd input/output parameters for compatibility
             // gives you a lot of helper functions -->
List of Functions
       Function      Description
       ───────────────────────────────────────────────────────────────────
       clearerr      check and reset stream status
       fclose        close a stream
       fdopen        stream open functions //( fd argument, returns FILE*)                      feof          check and reset stream status
       ferror        check and reset stream status
       fflush        flush a stream
       fgetc         get next character or word from input stream
       fgetpos       reposition a stream
       fgets         get a line from a stream
       fileno        get file descriptor   // (FILE* argument, returns fd) 
       fopen         stream open functions
       fprintf       formatted output conversion
       fpurge        flush a stream
       fputc         output a character or word to a stream
       fputs         output a line to a stream
       fread         binary stream input/output
       freopen       stream open functions
       fscanf        input format conversion
       fseek         reposition a stream
       fsetpos       reposition a stream
       ftell         reposition a stream
       fwrite        binary stream input/output
       getc          get next character or word from input stream
       getchar       get next character or word from input stream
       gets          get a line from a stream
       getw          get next character or word from input stream
       mktemp        make temporary filename (unique)
       perror        system error messages
       printf        formatted output conversion
       putc          output a character or word to a stream
       putchar       output a character or word to a stream
       puts          output a line to a stream
       putw          output a character or word to a stream
       remove        remove directory entry
       rewind        reposition a stream
       scanf         input format conversion
       setbuf        stream buffering operations
       setbuffer     stream buffering operations
       setlinebuf    stream buffering operations
       setvbuf       stream buffering operations
       sprintf       formatted output conversion
       sscanf        input format conversion
       strerror      system error messages
       sys_errlist   system error messages
       sys_nerr      system error messages
       tempnam       temporary file routines
       tmpfile       temporary file routines
       tmpnam        temporary file routines
       ungetc        un-get character from input stream
       vfprintf      formatted output conversion
       vfscanf       input format conversion
       vprintf       formatted output conversion
       vscanf        input format conversion
       vsprintf      formatted output conversion
       vsscanf       input format conversion

لذلك للاستخدام الأساسي، أود شخصيا استخدام ما ورد أعلاه دون خلط التعابير أكثر من اللازم.

على نقيض ذلك،

<unistd.h>   write()
             lseek()
             close()
             pipe()
<sys/types.h>
<sys/stat.h>
<fcntl.h>  open()
           creat()
           fcntl() 
all use file descriptors.

هذه توفر التحكم في الحبيبات الجميلة على القراءة والكتابة بايت (الموصى بها للأجهزة الخاصة والزيفوس (الأنابيب)).

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

ملاحظة-- إذا كنت تتداخل في CI / O بلغة أخرى، (Perl، Python، Java، C #، Lua ...) الدفع ما يوصي مطوري هذه اللغات قبل أن تكتب رمز C وإنقاذ نفسك بعض المتاعب.

يتم تخزين FOPEN وابن عمها. فتح، قراءة، والكتابة ليست مخزنة. قد يكون طلبك أو قد يهتم.

لدى FPRINTF و SCANF API الأكثر ثراء يسمح لك بقراءة الملفات النصية المنسقة والكتابة. قراءة والكتابة استخدام المصفوفات الأساسية من البايتات. يجب أن تكون التحويلات والتنسيق مصنوع يدويا.

الفرق بين ملفات الملفات و (الملف *) غير منطقي حقا.

راندي

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