تحويل وظيفة قراءة من سلسلة بدلا من ملف في C

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

  •  20-09-2019
  •  | 
  •  

سؤال

لقد تم تكليفي مع تحديث وظيفة يقرأ حاليا في تكوين ملف من القرص بملء الهيكل:

static int LoadFromFile(FILE *Stream, ConfigStructure *cs)
{
  int tempInt;

   ...

  if ( fscanf( Stream, "Version: %d\n",&tempInt) != 1 )
  {
    printf("Unable to read version number\n");
    return 0;
  }
  cs->Version = tempInt;
   ...

}

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

static int LoadFromString(char *Stream, ConfigStructure *cs)

عدد قليل من الأشياء أن نلاحظ:

  • الحالي LoadFromFile وظيفة كثيفة بشكل لا يصدق و معقدة, قراءة عشرات النسخ من ملف التكوين في متوافق الطريقة التي يجعل ازدواجية الشاملة المنطق تماما الألم.
  • الوظائف التي تولد config و تلك التي قرأتها تنشأ تماما في أجزاء مختلفة من النظام القديم وبالتالي لا نشارك أي هياكل البيانات لذلك أنا لا يمكن أن تمر هذه مباشرة.أنا يمكن أن كتابة المجمع, ولكن مرة أخرى, سوف تحتاج إلى التعامل مع أي هيكل مرت في معكوس متوافق الطريقة.
  • أنا يميل إلى مجرد تمرير الملف كما هو في سلسلة (كما في النموذج أعلاه) و تحويل جميع fscanf إلى sscanf لكن يجب التعامل مع تزايد المؤشر على طول (ويحتمل أن التعامل مع المخزن المؤقت تجاوز أخطاء) يدويا.
  • هذا يجب أن يبقى في ج ، لذلك لا C++ وظائف مثل تيارات يمكن أن تساعد هنا

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

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

المحلول

منذ كنت في محاولة للحفاظ على بيانات الملف في الذاكرة ، يجب أن تكون قادرا على استخدام الذاكرة المشتركة.POSIX الذاكرة المشتركة هو في الواقع اختلاف تعيين الذاكرة.الذاكرة المشتركة كائن يمكن تعيينها إلى مساحة عنوان العملية باستخدام mmap() إذا لزم الأمر.الذاكرة المشتركة عادة ما تستخدم باعتبارها IPC آلية, ولكن يجب أن تكون قادرة على استخدامها من أجل الوضع الخاص بك.

المثال التالي يستخدم رمز POSIX الذاكرة المشتركة (shm_open() & shm_unlink()) بالتعاون مع FILE * لكتابة النص إلى الذاكرة المشتركة الكائن ثم قراءتها مرة أخرى.

#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>
#include <sys/types.h>

#define MAX_LEN 1024

int main(int argc, char ** argv)
{
    int    fd;
    FILE * fp;
    char * buf[MAX_LEN];

    fd = shm_open("/test", O_CREAT | O_RDWR, 0600);

    ftruncate(fd, MAX_LEN);

    fp = fdopen(fd, "r+");

    fprintf(fp, "Hello_World!\n");

    rewind(fp);

    fscanf(fp, "%s", buf);

    fprintf(stdout, "%s\n", buf);

    fclose(fp);

    shm_unlink("/test");

    return 0;
}

ملاحظة:كان لي بالمرور -lrt إلى رابط عند ترجمة هذا المثال مع دول مجلس التعاون الخليجي على لينكس.

نصائح أخرى

إذا كنت لا يمكن أن تمر هياكل يجب تمرير البيانات كسلسلة ، ثم يجب أن تكون قادرة على قرص وظيفة الخاص بك إلى قراءة من سلسلة بدلا من ملف.إذا هي وظيفة معقدة كما تصفون ، ثم تحويل fscanf->sscanf ربما تكون الطريقة الأكثر مباشرة للذهاب.

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

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

  • استخدام mkstemp() إنشاء ملف مؤقت.فإنه يأخذ char * كما حجة ويستخدم كنموذج اسم الملف.ولكن فإنه سيعود ملف واصف.

  • استخدام tmpfile().فإنه يعود FILE *, ولكن لديه بعض القضايا الأمنية و أيضا, يمكنك نسخ سلسلة نفسك.

  • استخدام mmap() ( Beej دليل للمساعدة)

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