C # - قراءة من ملف السجل الثنائي يتم تحديثه كل 6 ثوان مع 12K من البيانات

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

  •  19-09-2019
  •  | 
  •  

سؤال

لدي ملف سجل ثنائي مع دفق البيانات من جهاز استشعار (INT16).
كل 6 ثوان، تتم إضافة 6000 عينات من النوع INT16، حتى يتم قطع اتصال المستشعر.

أحتاج إلى استطلاع هذا الملف على فترات منتظمة، متابعة من آخر موقف قراءة. هل من الأفضل أ) احتفظ بفارق ومفائمين للقارئ الثنائي ومفانورة بين قراءات B) إنشاء مثيل للمظير والقارئ الثنائي في كل مرة أحتاج فيها إلى القراءة (والحفاظ على متغير خارجي لتتبع آخر موضع قراءة) ج) شيء أفضل؟

تحرير: بعض الاقتراحات الرائعة حتى الآن، تحتاج إلى إضافة تطبيق "خادم" يتم توفيره بواسطة بائع مصدر خارجي ولا يمكن تعديله.

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

المحلول

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

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

نصائح أخرى

هل تستطيع استعمال memorymaptfiles.?

إذا استطعت، قم بإعادة تعيين الملف في الذاكرة ومشاركةها بين العمليات، فستتمكن من قراءة البيانات بزيادة الإزاحة ببساطة لمؤشرك في كل مرة.

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

أود أن أوصي باستخدام الأنابيب، فإنها تتصرف تماما مثل الملفات، باستثناء دفق البيانات مباشرة بين التطبيقات، حتى إذا كانت التطبيقات تعمل على أجهزة كمبيوتر مختلفة (على الرغم من أن هذا هو حقا خيار فقط إذا كنت قادرا على تغيير كل من التطبيقتين). التحقق من اسم اسم اسم "system.io.io.pipes".

ملاحظة: ستستخدم أنبوب "المسمى" لهذا (يتم دعم الأنابيب في "C" أيضا، لذلك في الأساس أي لغة برمجة نصف لائقة يجب أن تكون قادرة على تنفيذها)

أعتقد أن (أ) هو الأفضل لأن:

  • سيتم زيادة الوضع الحالي كما تقرأ ولا داعي للقلق بشأن تخزينها في مكان ما؛
  • لا تحتاج إلى فتحه والبحث عن الموضع المطلوب (لا ينبغي أن يكون أبطأ بكثير لإعادة فتحه ولكن إبقائه يفتح يمنح نظام التشغيل بعض تلميحات للتحسين والأعتقد) في كل مرة تقوم فيها باستطلاع عليه؛
  • الحلول الأخرى التي يمكنني التفكير بها تتطلب pinvokes إلى بدائريات مزامنة الانبثام النظام. ولن يكونوا أسرع من عمليات الملفات بالفعل في الإطار.

تحتاج فقط إلى تعيين إشارات Fileshare المناسبة:

فقط على سبيل المثال:

الخادم:

using(var writer = new BinaryWriter(new FileStream(@"D:\testlog.log", FileMode.Append, FileAccess.Write, FileShare.Read)))
{
    int n;
    while(Int32.TryParse(Console.ReadLine(), out n))
    {
        writer.Write(n);
        writer.Flush(); // write cached bytes to file
    }
}

عميل:

using (var reader = new BinaryReader(new FileStream(@"D:\testlog.log", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)))
{
    string s;
    while (Console.ReadLine() != "exit")
    {
        // allocate buffer for new ints
        Int32[] buffer = new Int32[(reader.BaseStream.Length - reader.BaseStream.Position) / sizeof(Int32)];

        Console.WriteLine("Stream length: {0}", reader.BaseStream.Length);
        Console.Write("Ints read: ");
        for (int i = 0; i < buffer.Length; i++)
        {
            buffer[i] = reader.ReadInt32();
            Console.Write((i == 0 ? "" : ", ") + buffer[i].ToString());
        }
        Console.WriteLine();
    }
}

يمكنك أيضا دفق البيانات في قاعدة بيانات، بدلا من ملف كبديل آخر، فلن تقلق بشأن قفل الملفات.

ولكن إذا كنت عالقا مع طريقة الملف، فقد ترغب في إغلاق الملف في كل مرة تقرأ فيها البيانات منه؛ يعتمد ذلك على الكثير على مدى تعقيد عملية الكتابة إلى الملف، وما إذا كان يمكن اكتشاف عملية قفل الملفات والاستجابة بشكل مناسب دون تحطيمها بشكل فظيع.

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