Csvhelper: الحصول على العد

تم إنشاؤها على ١٢ مارس ٢٠١٨  ·  5تعليقات  ·  مصدر: JoshClose/CsvHelper

لدي مشكلة مماثلة في # 92. لكنني لست متأكدًا مما إذا كان يجب أن أتصدى للمشكلة التي مضى عليها أكثر من 5 سنوات ، لذلك أقوم بإنشاء واحدة جديدة.

أدرك أن استدعاء Count() في السجلات التي تم تعدادها سيؤدي إلى انتقال المؤشر إلى النهاية ولن تؤدي العملية الإضافية / foreach loop في السجلات إلى إرجاع أي شيء.

مخطط الكود الخاص بي هو مثل هذا

ج #
var myCSV = new CsvReader (File.OpenText (txtBox_CSVFile.Text)) ؛
myCSV.Configuration.RegisterClassMap() ؛

var record = new MyRecordClass();
var allRecords = myCSV.EnumerateRecords(record);
int recordsLength = allRecords.Count<MyRecordClass>();

foreach (var r in allRecords)
{
    /* some read/write operation here
    */
    scannedCSVEntry++;
    progress.value = scannedCSVEntry/recordsLength;
}

""

recordsLength مهم هنا حيث أحتاج إلى تحديث شريط التقدم أثناء معالجة الإدخال

لكن كيف يمكنني الالتفاف حول هذا؟

التعليق الأكثر فائدة

إذا كنت تريد فقط تحديث شريط التقدم ، فإن استخدام stream.Position يعمل معي مع الملفات الكبيرة دون قراءة الملف بالكامل أولاً:

using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
   var csvReader = new new CsvHelper.CsvReader(sr);
    while (csvReader.Read())
    {
         double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
    }
}

يجب أن يعمل أيضًا مع GetRecords ، لكنني لم أختبر:

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}

ال 5 كومينتر

وهناك عدد قليل من الطرق.

  1. اسحب كل شيء إلى الذاكرة عن طريق عمل ToList . يمكنك بعد ذلك القيام بعدة عمليات على البيانات ، بما في ذلك Count .
  2. محلل الملف بأكمله. يمكنك استخدام المحلل اللغوي فقط لتصفح الملف بأكمله وعد السجلات. يجب أن يكون هذا سريعًا جدًا لأنه لا يقوم بإنشاء أي كائنات فئة أو إجراء أي نوع من التحويلات.
  3. فقط عد نهايات الأسطر في الملف. يمكنك بعد ذلك استخدام خاصية Context.RawRow لتحقيق تقدمك.

شكرا،
لقد اخترت أخيرًا الطريقة الثانية.

C# StreamReader sr = File.OpenText(txtBox_CSVFile.Text); int recordsLength = 0; while(sr.ReadLine() != null) { ++recordsLength; } recordsLength--; // discount 1 line because there are column headers in first row. Console.WriteLine("recordsLength : " + recordsLength); sr.Close();

هل يقوم EnumerateRecords() بإغلاق الدفق تلقائيًا بعد ترطيب جميع الإدخالات؟ أتساءل عما إذا كان يجب علي الاتصال بـ Close() بعد استدعاء الوظيفة.

اقتراحي هو الالتفاف في كتلة using .

using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
    int recordsLength = 0;
    while(sr.ReadLine() != null)
    {
        ++recordsLength;
    }
    recordsLength--; // discount 1 line because there are column headers in first row.
    Console.WriteLine("recordsLength : " + recordsLength);
}

إذا كنت تريد فقط تحديث شريط التقدم ، فإن استخدام stream.Position يعمل معي مع الملفات الكبيرة دون قراءة الملف بالكامل أولاً:

using(StreamReader sr = File.OpenText(txtBox_CSVFile.Text))
{
   var csvReader = new new CsvHelper.CsvReader(sr);
    while (csvReader.Read())
    {
         double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
    }
}

يجب أن يعمل أيضًا مع GetRecords ، لكنني لم أختبر:

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}

لقد راجعت الحل الخاص بك

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)sr.BaseStream.Position / sr.BaseStream.Length;
}

الذي لم يعمل معي.
لكن يمكنك فعل هذا

foreach(var record in csvReader.GetRecords<MyRecordClass>())
{
    double progress = (double)csvReader.Context.CharPosition / csvReader.Context.CharsRead;
}

للحصول على النتيجة المرجوة

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات