শিরোনাম সহ সি # তে সিএসভি ফাইলগুলি পার্স করা হচ্ছে


264

সি # তে সিএসভি ফাইলগুলি পার্স করার কোনও ডিফল্ট / অফিসিয়াল / প্রস্তাবিত উপায় আছে কি? আমি নিজের পার্সারটি রোল করতে চাই না।

এছাড়াও, আমি টেক্সট ড্রাইভারের মাধ্যমে সিএসভি পড়ার জন্য ওডিবিসি / ওএলই ডিবি ব্যবহার করার উদাহরণগুলি দেখেছি এবং এর "ত্রুটিগুলি" থাকার কারণে প্রচুর লোক এটিকে নিরুৎসাহিত করে। এই ত্রুটিগুলি কি কি?

আদর্শভাবে, আমি এমন একটি উপায় খুঁজছি যার মাধ্যমে আমি শিরোনাম / ক্ষেত্রের নাম হিসাবে প্রথম রেকর্ডটি ব্যবহার করে কলাম নাম দিয়ে সিএসভি পড়তে পারি। প্রদত্ত কয়েকটি উত্তর সঠিক হলেও মূলত ক্লাসে ফাইলটি ডিসেরায়াল করার কাজ করে।

উত্তর:


138

একটি লাইব্রেরি আপনার জন্য সমস্ত কৌতুকপূর্ণ-বিব্রত বিবরণ হ্যান্ডেল করতে দিন! :-)

ফাইলহেল্পারগুলি দেখুন এবং DRY থাকুন - নিজেকে পুনরাবৃত্তি করবেন না - চাকাটি গাজিলিয়নতম বার পুনরায় আবিষ্কার করার দরকার নেই ....

আপনার মূলত আপনাকে কেবলমাত্র আপনার ডেটাটির সেই আকারটি নির্ধারণ করতে হবে - সিএসভিতে আপনার নিজস্ব লাইনের ক্ষেত্রগুলি - একটি সার্বজনীন শ্রেণির মাধ্যমে (এবং তাই ডিফল্ট মান, NULL মানগুলির প্রতিস্থাপনের মতো বিশদযুক্ত গুণাবলী) এবং পয়েন্ট একটি ফাইলের ফাইলহেল্পার ইঞ্জিন, এবং বিঙ্গো - আপনি এই ফাইলটি থেকে সমস্ত এন্ট্রি ফিরে পাবেন। একটি সাধারণ অপারেশন - দুর্দান্ত পারফরম্যান্স!


1
যতক্ষণ না আপনার স্টাচ কাস্টমের প্রয়োজন হয় (এবং এর বেশিরভাগ ক্ষেত্রেই এক্সটেনশন হিসাবে প্রয়োগ করা যেতে পারে) ফাইলহেল্পাররা এখন পর্যন্ত সবচেয়ে ভাল উপায়, সত্যই সুবিধাজনক, পরীক্ষিত এবং ভাল পারফরম্যান্স সমাধান
মিকাস

3
1 ম জুন 2015 পর্যন্ত, আমি ফাইলহেলপার্স ডাউনলোড করতে পারার একমাত্র উপায় ছিল সোর্সফোর্জন.নেটে এটি অনুসন্ধান করা। এখানে লিঙ্কটি ব্যবহার করা হয়েছে: সোর্সফোর্জন.
नेट

2
@ ডটনেগগুয়ে আমরা ৩.১ প্রকাশের পথে রয়েছি (বর্তমানে ৩.১-আরসি 2) বাইরে গেছে। এছাড়াও আমরা সাইটটি নতুনভাবে ডিজাইন করেছি: www.filehelpers.net আপনি সেখান থেকে সর্বশেষ সংস্করণটি ডাউনলোড করতে পারেন
মার্কোস মেলি

1
@ মারকোস মেলী অনেক ধন্যবাদ! আমি ইতিমধ্যে আমার একটি প্রকল্পে ফাইলহেল্পার ব্যবহার করেছি এবং এটি দলে কুডো ব্যবহারের জন্য একটি হাওয়া ছিল। আমি শীঘ্রই এটিতে একটি ব্লগের পরিকল্পনা করছি এবং বিটিডব্লিউ - নতুন সাইটটি পছন্দ করুন - ভাল হয়েছে!
সুধাংশু মিশ্র

ফাইলহেল্পাররা সিএসভিগুলিতে উদ্ধৃত কমাগুলি সঠিকভাবে পরিচালনা করতে পারে না, বা ক্ষেত্রের শিরোনামগুলিতে ম্যাপ করে, পরিবর্তে প্রত্যাশা করে যে কলামগুলি একই ক্রমে আপনার ক্ষেত্রগুলি যেমন প্রকারে ঘোষিত হয়েছে। আমি ব্যক্তিগতভাবে এটি ব্যবহার করব না।
অ্যালাস্টার মাউ

356

একটি সিএসভি পার্সার এখন .NET ফ্রেমওয়ার্কের একটি অংশ।

মাইক্রোসফ্টে একটি রেফারেন্স যুক্ত করুন is ভিজুয়ালবাসিক.ডিল (সি # তে ভাল কাজ করে, নাম মনে করবেন না)

using (TextFieldParser parser = new TextFieldParser(@"c:\temp\test.csv"))
{
    parser.TextFieldType = FieldType.Delimited;
    parser.SetDelimiters(",");
    while (!parser.EndOfData)
    {
        //Process row
        string[] fields = parser.ReadFields();
        foreach (string field in fields)
        {
            //TODO: Process field
        }
    }
}

দস্তাবেজগুলি এখানে রয়েছে - টেক্সটফিল্ড পার্সার ক্লাস

পিএস যদি আপনার কোনও সিএসভি রফতানিকারক প্রয়োজন হয় তবে সিএসভিএক্সপোর্টের চেষ্টা করুন (ডিস্কেল: আমি অন্যতম অবদানকারী)


2
আমার অভিজ্ঞতা থেকে টেক্সটফিল্ড পার্সার বড় (উদাহরণস্বরূপ> 250Mb) ফাইলের সাথে ভাল সম্পাদন করে না। :(
এমবিরোস

6
টেক্সটফিল্ড পার্সার আইডিস্পোজেবল প্রয়োগ করে, তাই এটির ব্যবহারের ধারাটিতে এটি ব্যবহার করা ভাল। অন্যথায় ভাল উত্তর।
ক্রিস বুশ

3
কনস্ট্রাক্টরটিতে আপনি ডিফল্টর চেয়ে আলাদা এনকোডিংটি ব্যবহার করতে পারেন, যেমন: নতুন টেক্সটফিল্ড পার্সার ("সি: \ টেম্পি .c টেস্ট.সিএভিভি",
সিস্টেম.টেক্সট.ইনকোডিং.উইফএফ 8

1
মনে রাখবেন যে আপনার সিএসভিতে কোনও ক্ষেত্রে যদি ফাঁকা লাইন থাকে তবে সেগুলি এড়িয়ে চলে যাবে TextFieldParser.ReadLine()টেক্সটফিল্ড পার্সার ডক্স
mcNux

3
.NET কোর এ পাওয়ার কোনও উপায় আছে কি?
হুগো জিংক

183

সিএসভিহেল্পার (আমার রক্ষণাবেক্ষণ করা একটি গ্রন্থাগার) কাস্টম অবজেক্টে একটি সিএসভি ফাইল পড়বে।

var csv = new CsvReader( File.OpenText( "file.csv" ) );
var myCustomObjects = csv.GetRecords<MyCustomObject>();

কখনও কখনও আপনি যে বিষয়গুলিতে পড়ার চেষ্টা করছেন তা আপনার নিজস্ব নয়। এই ক্ষেত্রে, আপনি সাবলীল ম্যাপিং ব্যবহার করতে পারেন কারণ আপনি ক্লাসে বৈশিষ্ট্য রাখতে পারবেন না put

public sealed class MyCustomObjectMap : CsvClassMap<MyCustomObject>
{
    public MyCustomObjectMap()
    {
        Map( m => m.Property1 ).Name( "Column Name" );
        Map( m => m.Property2 ).Index( 4 );
        Map( m => m.Property3 ).Ignore();
        Map( m => m.Property4 ).TypeConverter<MySpecialTypeConverter>();
    }
}

সম্পাদনা করুন:

CSvReader এর এখন কন্ডাক্টর ( https://github.com/JoshClose/CsvHelper/issues/1441 ) এ পাস করা কালচারআইনফোর প্রয়োজন ।

উদাহরণ:

var csv = new CsvReader(File.OpenText("file.csv"), System.Globalization.CultureInfo.CurrentCulture);

18
আমি @ কুবল 5003 এর সাথে একমত এতে আমাকে কী বিক্রি হয়েছিল তা নুগেট প্যাকেজ হিসাবে আপনার কাছে উপলব্ধ ছিল। থ্যাঙ্কস ম্যান, এটি দ্রুত, এবং আমার প্রয়োজন সমস্ত সিএসভি রিডিং করে।
গ্রোমার 15

7
এটা খুব দ্রুত। ১.৩ মিলিয়ন রেকর্ডগুলি 10 সেকেন্ডে পড়ে এবং deserialized হয়।
16:13

2
কার্যকর করার জন্য দুর্দান্ত লাইব্রেরি। আমি কেবল জোশকে তার উত্তরটি এখানে আপডেট করার জন্য পরামর্শ দেব কারণ এই উত্তরটি লেখা হওয়ার পরে গ্রন্থাগারটি কিছুটা পরিবর্তিত হয়েছে এবং আপনি CSvHelper আর ইনস্ট্যান্ট করতে পারবেন না (এটি এখন কেবল একটি নামস্থান) তবে আপনাকে CSvReader শ্রেণি ব্যবহার করতে হবে।
মার্কো

1
CSvClassMap CsvHelper এর শেষ সংস্করণে উপস্থিত রয়েছে বলে মনে হচ্ছে না?
নোকট করুন

1
নক, এটিকে এখন ক্লাসম্যাপ বলা হয়। অন্যান্য পরিবর্তনগুলিও রয়েছে, যেমন শিরোনাম রেকর্ডের জন্য জিজ্ঞাসা করার আগে একটি পঠন করা (যা রিডে প্রথম কল করে যা পড়েছিল তা সেট করে) ()। অন্যরা যেমন পূর্বে উল্লেখ করেছে, এটি সুপারফায়েস্ট এবং কাজ করা সহজ।
নর্জি

31

একটি ব্যবসায়িক অ্যাপ্লিকেশনে, আমি কোডেপ্রজেক্ট.কম, সিএসভিআরডার ওপেন সোর্স প্রকল্প ব্যবহার করি

এটি ভাল কাজ করে, এবং ভাল অভিনয় আছে। আমি সরবরাহিত লিঙ্কটিতে কিছু বেঞ্চমার্কিং রয়েছে।

একটি সহজ উদাহরণ, প্রকল্প পৃষ্ঠা থেকে অনুলিপি করা:

using (CsvReader csv = new CsvReader(new StreamReader("data.csv"), true))
{
    int fieldCount = csv.FieldCount;
    string[] headers = csv.GetFieldHeaders();

    while (csv.ReadNextRecord())
    {
        for (int i = 0; i < fieldCount; i++)
            Console.Write(string.Format("{0} = {1};", headers[i], csv[i]));

        Console.WriteLine();
    }
}

আপনি দেখতে পাচ্ছেন যে এটির সাথে কাজ করা খুব সহজ।


20

আমি এটি কিছুটা দেরিতে জানি তবে সবেমাত্র একটি লাইব্রেরি পেয়েছি Microsoft.VisualBasic.FileIOযার TextFieldParserসিএসভি ফাইলগুলি প্রসেস করার ক্লাস রয়েছে ।


1
সেই এপিআই ব্যবহার করে একটি উদাহরণ; এমএসডিএন.মাইক্রোসফট.এইন.উস
লিবারি /cakac7e6(v=vs.90).aspx

12

আপনার যদি কেবল সিএসভি ফাইল পড়ার প্রয়োজন হয় তবে আমি এই লাইব্রেরিটি সুপারিশ করছি: একটি দ্রুত সিএসভি রিডার
যদি আপনারও সিএসভি ফাইল তৈরি করতে হয় তবে এইটি ব্যবহার করুন: ফাইলহেল্পারস

উভয়ই বিনামূল্যে এবং ওপেনসোর্স।


ফাইলহেল্পারগুলির একটি আকর্ষণীয় সংক্ষিপ্তসার রয়েছে: filehelpers.com ফাইলহেল্পার্স ফাইল, স্ট্রিং বা স্ট্রিমগুলিতে স্থির দৈর্ঘ্য বা সীমিত রেকর্ড থেকে ডেটা আমদানি / রফতানি করতে নেট নেট লাইব্রেরি use
অ্যানি দ্য অ্যাজিল

এই লিঙ্কটি যদি প্রশ্নের উত্তর দিতে পারে তবে লিঙ্কটি কেবল উত্তরগুলি স্ট্যাক ওভারফ্লোতে নিরুৎসাহিত করা হয়, আপনি লিঙ্কটির গুরুত্বপূর্ণ অংশগুলি গ্রহণ করে এবং আপনার উত্তরে রেখে এই উত্তরটি উন্নত করতে পারেন, এটি নিশ্চিত করে যদি আপনার উত্তরটি এখনও উত্তর হয় তবে লিঙ্কটি পরিবর্তন হয়ে যায় বা সরানো হয়েছে :)
হোয়াইটপয়েন্ট

11

এখানে আমি প্রায়শই ব্যবহার করি এমন একটি সহায়ক শ্রেণি রয়েছে, যদি কেউ এই থ্রেডে ফিরে আসে (আমি এটি ভাগ করতে চেয়েছিলাম)।

আমি এটি ব্যবহারের জন্য প্রস্তুত প্রকল্পগুলিতে পোর্টিংয়ের সরলতার জন্য এটি ব্যবহার করি:

public class CSVHelper : List<string[]>
{
  protected string csv = string.Empty;
  protected string separator = ",";

  public CSVHelper(string csv, string separator = "\",\"")
  {
    this.csv = csv;
    this.separator = separator;

    foreach (string line in Regex.Split(csv, System.Environment.NewLine).ToList().Where(s => !string.IsNullOrEmpty(s)))
    {
      string[] values = Regex.Split(line, separator);

      for (int i = 0; i < values.Length; i++)
      {
        //Trim values
        values[i] = values[i].Trim('\"');
      }

      this.Add(values);
    }
  }
}

এবং এটি ব্যবহার করুন:

public List<Person> GetPeople(string csvContent)
{
  List<Person> people = new List<Person>();
  CSVHelper csv = new CSVHelper(csvContent);
  foreach(string[] line in csv)
  {
    Person person = new Person();
    person.Name = line[0];
    person.TelephoneNo = line[1];
    people.Add(person);
  }
  return people;
}

[সিএসভি সহায়ক আপডেট হয়েছে: শেষের নতুন রেখার অক্ষরটি একটি নতুন লাইন তৈরি করেছে সেখানে বাগটি ঠিক করা হয়েছে]


17
যদি কোনও সিএসভি এন্ট্রিগুলিতে কমা থাকে (,) এই কোডটি কাজ করবে না।
হকান

জিনিসগুলিকে হালকা ওজনের রাখতে, আমি পৃথককারী হিসাবে পাইপের চরিত্রটি ব্যবহার করেছি। '|'
বেস 33

চমৎকার সমাধান। ২ য় স্নিপেট সম্পর্কে কেবল একটি প্রশ্ন। কী ধরণের ব্যক্তি হ'ল ব্যক্তি
কোকো দেব

@ কোকোদেভ এটি এমন একটি শ্রেণী যা নাম এবং টেলিফোন না দুটি স্ট্রিং বৈশিষ্ট্য ধারণ করে। নিখুঁতভাবে উদাহরণের জন্য যদিও। বৈশিষ্ট্যগুলির মধ্যে কোনওটি যদি পূর্ণসংখ্যার হয় তবে এটি কেবল একটি সরাসরি সম্মুখ রূপান্তর হওয়া উচিত (চেক সহ?)
বেস 33

10

এই সমাধানটি সিএসভি পার্স করার জন্য অফিশিয়াল মাইক্রোসফ্ট.ভিউজুয়ালবাসিক অ্যাসেম্বলি ব্যবহার করছে ।

সুবিধাদি:

  • ডিলিমিটার পলায়ন
  • হেডার উপেক্ষা করুন
  • ট্রিম স্পেস
  • মন্তব্য উপেক্ষা করুন

কোড:

    using Microsoft.VisualBasic.FileIO;

    public static List<List<string>> ParseCSV (string csv)
    {
        List<List<string>> result = new List<List<string>>();


        // To use the TextFieldParser a reference to the Microsoft.VisualBasic assembly has to be added to the project. 
        using (TextFieldParser parser = new TextFieldParser(new StringReader(csv))) 
        {
            parser.CommentTokens = new string[] { "#" };
            parser.SetDelimiters(new string[] { ";" });
            parser.HasFieldsEnclosedInQuotes = true;

            // Skip over header line.
            //parser.ReadLine();

            while (!parser.EndOfData)
            {
                var values = new List<string>();

                var readFields = parser.ReadFields();
                if (readFields != null)
                    values.AddRange(readFields);
                result.Add(values);
            }
        }

        return result;
    }

7

আমি .NET- র জন্য টিনিসিএসভিপার্সার লিখেছি , যা প্রায় দ্রুততম নেট নেট পার্সারগুলির মধ্যে একটি এবং প্রায় কোনও সিএসভি ফর্ম্যাটকে পার্স করার জন্য অত্যন্ত কনফিগারযোগ্য।

এটি এমআইটি লাইসেন্সের আওতায় প্রকাশিত হয়েছে:

আপনি এটি ইনস্টল করতে নিউগেট ব্যবহার করতে পারেন । প্যাকেজ ম্যানেজার কনসোলে নিম্নলিখিত কমান্ডটি চালান

PM> Install-Package TinyCsvParser

ব্যবহার

কল্পনা করুন যে কোনও CSV ফাইলে আমাদের persons.csvপ্রথম ব্যক্তির নাম, পদবি এবং জন্ম তারিখ সহ ব্যক্তিদের তালিকা রয়েছে ।

FirstName;LastName;BirthDate
Philipp;Wagner;1986/05/12
Max;Musterman;2014/01/02

আমাদের সিস্টেমে সম্পর্কিত ডোমেন মডেলটি এর মতো দেখতে পারে।

private class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }
}

TinyCsvParser ব্যবহার করার সময় আপনাকে সিএসভি ডেটাতে কলাম এবং আপনার ডোমেন মডেলের সম্পত্তিগুলির মধ্যে ম্যাপিংটি সংজ্ঞায়িত করতে হবে।

private class CsvPersonMapping : CsvMapping<Person>
{

    public CsvPersonMapping()
        : base()
    {
        MapProperty(0, x => x.FirstName);
        MapProperty(1, x => x.LastName);
        MapProperty(2, x => x.BirthDate);
    }
}

এবং তারপরে আমরা ম্যাসিটিংটি CSV ডেটার সাথে a ব্যবহার করতে পারি CsvParser

namespace TinyCsvParser.Test
{
    [TestFixture]
    public class TinyCsvParserTest
    {
        [Test]
        public void TinyCsvTest()
        {
            CsvParserOptions csvParserOptions = new CsvParserOptions(true, new[] { ';' });
            CsvPersonMapping csvMapper = new CsvPersonMapping();
            CsvParser<Person> csvParser = new CsvParser<Person>(csvParserOptions, csvMapper);

            var result = csvParser
                .ReadFromFile(@"persons.csv", Encoding.ASCII)
                .ToList();

            Assert.AreEqual(2, result.Count);

            Assert.IsTrue(result.All(x => x.IsValid));

            Assert.AreEqual("Philipp", result[0].Result.FirstName);
            Assert.AreEqual("Wagner", result[0].Result.LastName);

            Assert.AreEqual(1986, result[0].Result.BirthDate.Year);
            Assert.AreEqual(5, result[0].Result.BirthDate.Month);
            Assert.AreEqual(12, result[0].Result.BirthDate.Day);

            Assert.AreEqual("Max", result[1].Result.FirstName);
            Assert.AreEqual("Mustermann", result[1].Result.LastName);

            Assert.AreEqual(2014, result[1].Result.BirthDate.Year);
            Assert.AreEqual(1, result[1].Result.BirthDate.Month);
            Assert.AreEqual(1, result[1].Result.BirthDate.Day);
        }
    }
}

ব্যবহারকারী গাইড

একটি পূর্ণ ব্যবহারকারী গাইড এখানে পাওয়া যায়:


1

এখানে আমার KISS বাস্তবায়ন ...

using System;
using System.Collections.Generic;
using System.Text;

class CsvParser
{
    public static List<string> Parse(string line)
    {
        const char escapeChar = '"';
        const char splitChar = ',';
        bool inEscape = false;
        bool priorEscape = false;

        List<string> result = new List<string>();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < line.Length; i++)
        {
            char c = line[i];
            switch (c)
            {
                case escapeChar:
                    if (!inEscape)
                        inEscape = true;
                    else
                    {
                        if (!priorEscape)
                        {
                            if (i + 1 < line.Length && line[i + 1] == escapeChar)
                                priorEscape = true;
                            else
                                inEscape = false;
                        }
                        else
                        {
                            sb.Append(c);
                            priorEscape = false;
                        }
                    }
                    break;
                case splitChar:
                    if (inEscape) //if in escape
                        sb.Append(c);
                    else
                    {
                        result.Add(sb.ToString());
                        sb.Length = 0;
                    }
                    break;
                default:
                    sb.Append(c);
                    break;
            }
        }

        if (sb.Length > 0)
            result.Add(sb.ToString());

        return result;
    }

}

1
এটি উদ্ধৃত স্ট্রিংয়ের মধ্যে লাইন বিরতি নিয়ে কাজ করে না যা কোনও সিএসভি ফাইলে বৈধ।
জন লেইডগ্রেন

অ্যালেক্স, জন যা বলার চেষ্টা করছে তা হ'ল আরএফসি 4180 ( ietf.org/rfc/rfc4180.txt - বিভাগ 2 এবং আইটেম দেখুন 6) একটি কলামকে একটি কলামের মাঝখানে একটি সিআর এলএফ কার্যকরভাবে ছড়িয়ে দেওয়ার অনুমতি দেয় একটি ফাইল 2 লাইন। আপনার সমাধান সম্ভবত বেশিরভাগ ক্ষেত্রে ভাল কাজ করবে (বিশেষত যদি CSV ফাইলগুলি এক্সেলের বাইরে সঞ্চয় করে তৈরি করা হয়েছিল) তবে এটি এই প্রান্তের কেসটি আবরণ করে না। উপরে উল্লিখিত সিএসভিহেল্পার এই মামলাটি বিবেচনায় নেবে বলে মনে করা হচ্ছে।
ডেভিড ইয়েটস

হ্যাঁ, এটি সত্য, তবে আপনার সিএসভিতে সিআর এলএফ থাকলে আপনার সম্ভবত সিএসভি ব্যবহার করা উচিত নয়, তবে আরও উপযুক্ত কিছু, জসন বা এক্সএমএল বা স্থির দৈর্ঘ্যের ফর্ম্যাট।
অ্যালেক্স বেগুন

1

কিছু সময় আগে আমি Microsoft.VisualBasicলাইব্রেরির উপর ভিত্তি করে সিএসভি পড়ার / লেখার জন্য সহজ ক্লাস লিখেছিলাম । এই সাধারণ শ্রেণিটি ব্যবহার করে আপনি 2 টি মাত্রার অ্যারের মতো সিএসভিতে কাজ করতে সক্ষম হবেন। আপনি আমার নীচের লিঙ্কটি দ্বারা ক্লাস খুঁজে পেতে পারেন: https://github.com/ukushu/DataExporter

ব্যবহারের সহজ উদাহরণ:

Csv csv = new Csv("\t");//delimiter symbol

csv.FileOpen("c:\\file1.csv");

var row1Cell6Value = csv.Rows[0][5];

csv.AddRow("asdf","asdffffff","5")

csv.FileSave("c:\\file2.csv");

শিরোনাম পড়ার জন্য কেবল আপনার প্রয়োজন csv.Rows[0]সেলগুলি :)


1

সোজা পার্সিংয়ের প্রয়োজনীয়তার জন্য একক উত্স ফাইল সমাধান। সমস্ত কদর্য প্রান্ত মামলা সঙ্গে ডিল। যেমন নতুন লাইনের নরমালাইজেশন এবং উদ্ধৃত স্ট্রিং লিটারেলগুলিতে নতুন লাইনগুলি পরিচালনা করা। আপনাকে স্বাগতম!

যদি আপনার সিএসভি ফাইলের শিরোনাম থাকে তবে আপনি প্রথম সারির থেকে কলামের নামগুলি (এবং গণনা কলাম সূচীগুলি) পড়বেন। যে হিসাবে সহজ।

মনে রাখবেন যে Dump লিনকুইপ্যাড পদ্ধতি, আপনি যদি লিনকপ্যাড ব্যবহার না করেন তবে আপনি তা সরাতে চাইবেন।

void Main()
{
    var file1 = "a,b,c\r\nx,y,z";
    CSV.ParseText(file1).Dump();

    var file2 = "a,\"b\",c\r\nx,\"y,z\"";
    CSV.ParseText(file2).Dump();

    var file3 = "a,\"b\",c\r\nx,\"y\r\nz\"";
    CSV.ParseText(file3).Dump();

    var file4 = "\"\"\"\"";
    CSV.ParseText(file4).Dump();
}

static class CSV
{
    public struct Record
    {
        public readonly string[] Row;

        public string this[int index] => Row[index];

        public Record(string[] row)
        {
            Row = row;
        }
    }

    public static List<Record> ParseText(string text)
    {
        return Parse(new StringReader(text));
    }

    public static List<Record> ParseFile(string fn)
    {
        using (var reader = File.OpenText(fn))
        {
            return Parse(reader);
        }
    }

    public static List<Record> Parse(TextReader reader)
    {
        var data = new List<Record>();

        var col = new StringBuilder();
        var row = new List<string>();
        for (; ; )
        {
            var ln = reader.ReadLine();
            if (ln == null) break;
            if (Tokenize(ln, col, row))
            {
                data.Add(new Record(row.ToArray()));
                row.Clear();
            }
        }

        return data;
    }

    public static bool Tokenize(string s, StringBuilder col, List<string> row)
    {
        int i = 0;

        if (col.Length > 0)
        {
            col.AppendLine(); // continuation

            if (!TokenizeQuote(s, ref i, col, row))
            {
                return false;
            }
        }

        while (i < s.Length)
        {
            var ch = s[i];
            if (ch == ',')
            {
                row.Add(col.ToString().Trim());
                col.Length = 0;
                i++;
            }
            else if (ch == '"')
            {
                i++;
                if (!TokenizeQuote(s, ref i, col, row))
                {
                    return false;
                }
            }
            else
            {
                col.Append(ch);
                i++;
            }
        }

        if (col.Length > 0)
        {
            row.Add(col.ToString().Trim());
            col.Length = 0;
        }

        return true;
    }

    public static bool TokenizeQuote(string s, ref int i, StringBuilder col, List<string> row)
    {
        while (i < s.Length)
        {
            var ch = s[i];
            if (ch == '"')
            {
                // escape sequence
                if (i + 1 < s.Length && s[i + 1] == '"')
                {
                    col.Append('"');
                    i++;
                    i++;
                    continue;
                }
                i++;
                return true;
            }
            else
            {
                col.Append(ch);
                i++;
            }
        }
        return false;
    }
}

1

এই তালিকার আর একটি, সিনচু ইটিএল - একাধিক ফাইল ফর্ম্যাটগুলি পড়ার এবং লেখার জন্য একটি ওপেন সোর্স লাইব্রেরি (সিএসভি, ফ্ল্যাট ফাইল, এক্সএমএল, জেএসএন ইত্যাদি)

নীচে নমুনা দেখায় কীভাবে সিএসভি ফাইল দ্রুত পড়তে হয় (কোনও পোকো অবজেক্টের প্রয়োজন নেই)

string csv = @"Id, Name
1, Carl
2, Tom
3, Mark";

using (var p = ChoCSVReader.LoadText(csv)
    .WithFirstLineHeader()
    )
{
    foreach (var rec in p)
    {
        Console.WriteLine($"Id: {rec.Id}");
        Console.WriteLine($"Name: {rec.Name}");
    }
}

নীচে নমুনা দেখায় যে কীভাবে পোকো অবজেক্ট ব্যবহার করে সিএসভি ফাইলটি পড়তে হয়

public partial class EmployeeRec
{
    public int Id { get; set; }
    public string Name { get; set; }
}

static void CSVTest()
{
    string csv = @"Id, Name
1, Carl
2, Tom
3, Mark";

    using (var p = ChoCSVReader<EmployeeRec>.LoadText(csv)
        .WithFirstLineHeader()
        )
    {
        foreach (var rec in p)
        {
            Console.WriteLine($"Id: {rec.Id}");
            Console.WriteLine($"Name: {rec.Name}");
        }
    }
}

কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে দয়া করে কোডপ্রজেক্টে নিবন্ধগুলি দেখুন ।


0

সি # বিভক্ত () ফাংশনটি ব্যবহার করে কীভাবে কোনও সিএসভি সঠিকভাবে বিভক্ত করবেন সে বিষয়ে আনলিমিটের পোস্টের ভিত্তিতে ? :

string[] tokens = System.Text.RegularExpressions.Regex.Split(paramString, ",");

দ্রষ্টব্য: এটি পালিয়ে যাওয়া / নেস্টেড কমাগুলি ইত্যাদি পরিচালনা করে না এবং তাই কেবলমাত্র কয়েকটি সাধারণ সিএসভি তালিকার জন্য উপযুক্ত।


2
এটি খুব খারাপ এবং সম্ভবত ধীর :)
EKS

1
সম্ভবত, তবে এটি পরামিতিগুলির একটি ছোট সেটের জন্য নিখুঁত এবং সহজভাবে কাজ করে, সুতরাং এটি একটি বৈধ এবং সহায়ক সমাধান। এটাকে কেন ডাউনভোট করবেন? "ভেরি ব্যাড" একটু চরম, আপনার কি মনে হয় না?
র‌্যাডসডো

1
এটি পালানো / নেস্টেড কমা ইত্যাদি পরিচালনা করে না কিছু ক্ষেত্রে কাজ করবে তবে অবশ্যই সমস্ত
সিএসভি

আপনার ঠিক আছে; আমি প্রতিফলিত করতে উত্তর সম্পাদনা করব। ধন্যবাদ। তবে এর এখনও জায়গা আছে।
Radsdau

এটি আমার ব্যবহারের ক্ষেত্রে পুরোপুরি কাজ করেছে যেখানে আমি একটি স্কিএল সার্ভার তৈরি করছি clr dll এবং এই জাতীয় বাহ্যিক প্যাকেজগুলির কোনও ব্যবহার করতে পারি না। আমার কেবল একটি সরল সিএসভি ফাইলকে একটি ফাইলের নাম এবং সারি গণনার সাথে বিশ্লেষণ করতে হবে।
dubvfan87

0

এই কোডটি সিএসভিতে ডেটা টেবেলে পড়ে:

public static DataTable ReadCsv(string path)
{
    DataTable result = new DataTable("SomeData");
    using (TextFieldParser parser = new TextFieldParser(path))
    {
        parser.TextFieldType = FieldType.Delimited;
        parser.SetDelimiters(",");
        bool isFirstRow = true;
        //IList<string> headers = new List<string>();

        while (!parser.EndOfData)
        {
            string[] fields = parser.ReadFields();
            if (isFirstRow)
            {
                foreach (string field in fields)
                {
                    result.Columns.Add(new DataColumn(field, typeof(string)));
                }
                isFirstRow = false;
            }
            else
            {
                int i = 0;
                DataRow row = result.NewRow();
                foreach (string field in fields)
                {
                    row[i++] = field;
                }
                result.Rows.Add(row);
            }
        }
    }
    return result;
}

1
টেক্সটফিল্ড পার্সারটি মাইক্রোসফ্টে রয়েছে Vভিজুয়ালবাসিক.ডিল।
ব্যবহারকারী 3285954

0

যদি কেউ স্নিপেট চায় তবে তারা কোনও লাইব্রেরিকে বাঁধাই বা প্যাকেজ ডাউনলোড না করেই তাদের কোডে প্লপ করতে পারে। আমি লিখেছি একটি সংস্করণ এখানে:

    public static string FormatCSV(List<string> parts)
    {
        string result = "";

        foreach (string s in parts)
        {
            if (result.Length > 0)
            {
                result += ",";

                if (s.Length == 0)
                    continue;
            }

            if (s.Length > 0)
            {
                result += "\"" + s.Replace("\"", "\"\"") + "\"";
            }
            else
            {
                // cannot output double quotes since its considered an escape for a quote
                result += ",";
            }
        }

        return result;
    }

    enum CSVMode
    {
        CLOSED = 0,
        OPENED_RAW = 1,
        OPENED_QUOTE = 2
    }

    public static List<string> ParseCSV(string input)
    {
        List<string> results;

        CSVMode mode;

        char[] letters;

        string content;


        mode = CSVMode.CLOSED;

        content = "";
        results = new List<string>();
        letters = input.ToCharArray();

        for (int i = 0; i < letters.Length; i++)
        {
            char letter = letters[i];
            char nextLetter = '\0';

            if (i < letters.Length - 1)
                nextLetter = letters[i + 1];

            // If its a quote character
            if (letter == '"')
            {
                // If that next letter is a quote
                if (nextLetter == '"' && mode == CSVMode.OPENED_QUOTE)
                {
                    // Then this quote is escaped and should be added to the content

                    content += letter;

                    // Skip the escape character
                    i++;
                    continue;
                }
                else
                {
                    // otherwise its not an escaped quote and is an opening or closing one
                    // Character is skipped

                    // If it was open, then close it
                    if (mode == CSVMode.OPENED_QUOTE)
                    {
                        results.Add(content);

                        // reset the content
                        content = "";

                        mode = CSVMode.CLOSED;

                        // If there is a next letter available
                        if (nextLetter != '\0')
                        {
                            // If it is a comma
                            if (nextLetter == ',')
                            {
                                i++;
                                continue;
                            }
                            else
                            {
                                throw new Exception("Expected comma. Found: " + nextLetter);
                            }
                        }
                    }
                    else if (mode == CSVMode.OPENED_RAW)
                    {
                        // If it was opened raw, then just add the quote 
                        content += letter;
                    }
                    else if (mode == CSVMode.CLOSED)
                    {
                        // Otherwise open it as a quote 

                        mode = CSVMode.OPENED_QUOTE;
                    }
                }
            }
            // If its a comma seperator
            else if (letter == ',')
            {
                // If in quote mode
                if (mode == CSVMode.OPENED_QUOTE)
                {
                    // Just read it
                    content += letter;
                }
                // If raw, then close the content
                else if (mode == CSVMode.OPENED_RAW)
                {
                    results.Add(content);

                    content = "";

                    mode = CSVMode.CLOSED;
                }
                // If it was closed, then open it raw
                else if (mode == CSVMode.CLOSED)
                {
                    mode = CSVMode.OPENED_RAW;

                    results.Add(content);

                    content = "";
                }
            }
            else
            {
                // If opened quote, just read it
                if (mode == CSVMode.OPENED_QUOTE)
                {
                    content += letter;
                }
                // If opened raw, then read it
                else if (mode == CSVMode.OPENED_RAW)
                {
                    content += letter;
                }
                // It closed, then open raw
                else if (mode == CSVMode.CLOSED)
                {
                    mode = CSVMode.OPENED_RAW;

                    content += letter;
                }
            }
        }

        // If it was still reading when the buffer finished
        if (mode != CSVMode.CLOSED)
        {
            results.Add(content);
        }

        return results;
    }

0

একটি সংক্ষিপ্ত এবং সহজ সমাধান এখানে।

                using (TextFieldParser parser = new TextFieldParser(outputLocation))
                 {
                        parser.TextFieldType = FieldType.Delimited;
                        parser.SetDelimiters(",");
                        string[] headers = parser.ReadLine().Split(',');
                        foreach (string header in headers)
                        {
                            dataTable.Columns.Add(header);
                        }
                        while (!parser.EndOfData)
                        {
                            string[] fields = parser.ReadFields();
                            dataTable.Rows.Add(fields);
                        }
                    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.