لدي مشكلة مماثلة في # 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
مهم هنا حيث أحتاج إلى تحديث شريط التقدم أثناء معالجة الإدخال
لكن كيف يمكنني الالتفاف حول هذا؟
وهناك عدد قليل من الطرق.
ToList
. يمكنك بعد ذلك القيام بعدة عمليات على البيانات ، بما في ذلك Count
.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;
}
للحصول على النتيجة المرجوة
التعليق الأكثر فائدة
إذا كنت تريد فقط تحديث شريط التقدم ، فإن استخدام
stream.Position
يعمل معي مع الملفات الكبيرة دون قراءة الملف بالكامل أولاً:يجب أن يعمل أيضًا مع GetRecords ، لكنني لم أختبر: