। নেট [বন্ধ] তে দৃ in়ভাবে টাইপ করা ডেটা স্ট্রাকচারে সিএসভি ফাইল আমদানি করুন


106

দৃ CS়ভাবে টাইপ করা ডেটা স্ট্রাকচারে কোনও সিএসভি ফাইল আমদানির সর্বোত্তম উপায় কী?




7
এটি 1103495 এরও এক বছর আগে তৈরি হয়েছিল বিবেচনা করে, আমি মনে করি যে প্রশ্নটি এটির একটি সদৃশ।
ম্যাথএইচ

2
ধন্যবাদ, ম্যাট আমি তাদের সাথে কেবল লিঙ্ক দেওয়ার চেষ্টা করছিলাম, কোনটি আগে এসেছিল তা নির্দেশ করে না। আপনি দেখতে পাবেন যে আমার অন্য প্রশ্নের ঠিক একই পাঠ্যটি এটিকে দেখিয়েছি two দুটি প্রশ্ন বেঁধে রাখার আরও ভাল উপায় কি?
মার্ক মেউর

উত্তর:


74

মাইক্রোসফ্টের টেক্সটফিল্ড পার্সার স্থিতিশীল এবং সিএসভি ফাইলগুলির জন্য আরএফসি 4180 অনুসরণ করে। Microsoft.VisualBasicনেমস্পেসের কাছ থেকে দূরে থাকবেন না ; এটি। নেট ফ্রেমওয়ার্কের একটি স্ট্যান্ডার্ড উপাদান, কেবলমাত্র বিশ্ব Microsoft.VisualBasicসমাবেশে একটি রেফারেন্স যুক্ত করুন ।

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

আরও দেখুন: কীভাবে: ভিজুয়াল বেসিকের কমা-বিসীমাংসিত পাঠ্য ফাইলগুলি থেকে কোনও ভিবি কোড উদাহরণের জন্য পড়ুন।


2
দুর্ভাগ্যবশত নামযুক্ত স্থান ছাড়া এই শ্রেণীর সম্পর্কে আসলে ভিবি-নির্দিষ্ট কিছুই নেই। আমি কেবলমাত্র "সাধারণ" সিএসভি পার্সার প্রয়োজন হলে আমি অবশ্যই এই লাইব্রেরিটি বেছে নেব, কারণ সাধারণভাবে ডাউনলোড, বিতরণ বা উদ্বেগের কিছুই নেই। সে লক্ষ্যে আমি এই উত্তরটি থেকে বাইরে ভিবি-কেন্দ্রিক ফ্রেসিং সম্পাদনা করেছি।
অ্যারোনআট

@ অ্যারোনআউট আমি মনে করি আপনার সম্পাদনাগুলি বেশিরভাগ ক্ষেত্রে একটি উন্নতি। যদিও আরএফসি অগত্যা অনুমোদনযোগ্য নয়, অনেক সিএসভি লেখক এটি মেনে চলেন না যেমন এক্সেল সর্বদা "সিএসভি" ফাইলগুলিতে কমা ব্যবহার করে না । এছাড়াও আমার পূর্ববর্তী উত্তরটি ইতিমধ্যে বলেছিল না যে ক্লাসটি সি # থেকে ব্যবহার করা যেতে পারে?
মার্কজে

এটি TextFieldParserট্যাব-সীমাবদ্ধ এবং অন্যান্য অদ্ভুত এক্সেল-উত্পাদিত ক্রাফ্টের জন্যও কাজ করবে। আমি বুঝতে পেরেছি যে আপনার পূর্ববর্তী উত্তরটি দাবি করছিল না যে গ্রন্থাগারটি ভিবি-নির্দিষ্ট ছিল, এটি কেবলমাত্র আমার কাছে বোঝানো হয়েছিল যে এটি সত্যিকার অর্থেই ভিবির জন্য, এবং সি # থেকে ব্যবহার করার উদ্দেশ্যে নয় , যা আমি মনে করি না কেস - এমএসভিবিতে সত্যই দরকারী কিছু ক্লাস রয়েছে।
অ্যারোনআট

21

একটি OleDB সংযোগ ব্যবহার করুন।

String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\InputDirectory\\;Extended Properties='text;HDR=Yes;FMT=Delimited'";
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
DataTable dt = new DataTable();
OleDbCommand objCmdSelect = new OleDbCommand("SELECT * FROM file.csv", objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
objAdapter1.Fill(dt);
objConn.Close();

এর জন্য ফাইল সিস্টেম অ্যাক্সেস প্রয়োজন। আমি যতদূর জানি
ওএলইডিডিবি -কে

3
@ ইউজারকন্ট্রোল, অবশ্যই এটি ফাইল সিস্টেম অ্যাক্সেস প্রয়োজন requires তিনি একটি সিএসভি ফাইল আমদানি সম্পর্কে জিজ্ঞাসা করেছিলেন
কেভিন

1
আমি অভিযোগ করছি না. আসলে আমি বাকিগুলির চেয়ে ওএলডিবি সমাধানটি পছন্দ করব তবে এএসপি.এনইটি অ্যাপ্লিকেশনগুলিতে সিএসভি পার্স করার জন্য যখন আমি অনেকবার হতাশ হয়ে পড়েছিলাম তখন এটি নোট করতে চেয়েছিল।
ব্যবহারকারীর নিয়ন্ত্রণ

12

আপনি যদি সিএসভি পার্সিংয়ের জন্য মোটামুটি জটিল পরিস্থিতিতে প্রত্যাশা করে থাকেন তবে আমাদের নিজস্ব পার্সার ঘূর্ণায়মানটি ভাবেন না । সেখানে চমৎকার সরঞ্জাম অনেক, মত FileHelpers , অথবা থেকেও বেশী CodeProject

মুল বক্তব্যটি হ'ল এটি একটি মোটামুটি সাধারণ সমস্যা এবং আপনি বাজি ধরতে পারেন যে অনেক সফ্টওয়্যার বিকাশকারী ইতিমধ্যে এই সমস্যাটি সম্পর্কে চিন্তাভাবনা করেছেন এবং সমাধান করেছেন।


যদিও এই লিঙ্কটি প্রশ্নের উত্তর দিতে পারে, উত্তরের প্রয়োজনীয় অংশগুলি এখানে অন্তর্ভুক্ত করা এবং রেফারেন্সের জন্য লিঙ্কটি সরবরাহ করা ভাল। লিঙ্কযুক্ত উত্তর পরিবর্তিত হলে লিঙ্কযুক্ত উত্তরগুলি অবৈধ হতে পারে। - পর্যালোচনা থেকে
টেকস্পাইডার

ধন্যবাদ @ টেকস্পাইডার আমি আশা করি আপনি নোট করেছেন যে এই পোস্টটি স্ট্যাকওভারফ্লো এর বিটা পিরিয়ডের ছিল: ডি যে আজকাল বলা হচ্ছে সিএসভি সরঞ্জামগুলি নুগেট প্যাকেজগুলি থেকে আরও ভাল উত্সাহিত করা হয়েছে - তাই আমি নিশ্চিত নই যে লিঙ্কের উত্তরগুলিও 8-বছর থেকে সুরক্ষিত আছে কিনা? প্রযুক্তির
বহুল

9

ব্রায়ান দৃ strongly়ভাবে টাইপ করা সংগ্রহে রূপান্তর করার জন্য একটি দুর্দান্ত সমাধান দেয় gives

প্রদত্ত বেশিরভাগ CSV পার্সিংয়ের পদ্ধতিগুলি পালানোর ক্ষেত্রগুলি বা CSV ফাইলের অন্যান্য সূক্ষ্মতাগুলিকে (ট্রিমিং ফিল্ডের মতো) বিবেচনা করে না। আমি ব্যক্তিগতভাবে ব্যবহার করি কোডটি এখানে। এটি প্রান্তের চারপাশে কিছুটা রুক্ষ এবং এতে কোনও ত্রুটি প্রতিবেদন করার ক্ষমতা নেই।

public static IList<IList<string>> Parse(string content)
{
    IList<IList<string>> records = new List<IList<string>>();

    StringReader stringReader = new StringReader(content);

    bool inQoutedString = false;
    IList<string> record = new List<string>();
    StringBuilder fieldBuilder = new StringBuilder();
    while (stringReader.Peek() != -1)
    {
        char readChar = (char)stringReader.Read();

        if (readChar == '\n' || (readChar == '\r' && stringReader.Peek() == '\n'))
        {
            // If it's a \r\n combo consume the \n part and throw it away.
            if (readChar == '\r')
            {
                stringReader.Read();
            }

            if (inQoutedString)
            {
                if (readChar == '\r')
                {
                    fieldBuilder.Append('\r');
                }
                fieldBuilder.Append('\n');
            }
            else
            {
                record.Add(fieldBuilder.ToString().TrimEnd());
                fieldBuilder = new StringBuilder();

                records.Add(record);
                record = new List<string>();

                inQoutedString = false;
            }
        }
        else if (fieldBuilder.Length == 0 && !inQoutedString)
        {
            if (char.IsWhiteSpace(readChar))
            {
                // Ignore leading whitespace
            }
            else if (readChar == '"')
            {
                inQoutedString = true;
            }
            else if (readChar == ',')
            {
                record.Add(fieldBuilder.ToString().TrimEnd());
                fieldBuilder = new StringBuilder();
            }
            else
            {
                fieldBuilder.Append(readChar);
            }
        }
        else if (readChar == ',')
        {
            if (inQoutedString)
            {
                fieldBuilder.Append(',');
            }
            else
            {
                record.Add(fieldBuilder.ToString().TrimEnd());
                fieldBuilder = new StringBuilder();
            }
        }
        else if (readChar == '"')
        {
            if (inQoutedString)
            {
                if (stringReader.Peek() == '"')
                {
                    stringReader.Read();
                    fieldBuilder.Append('"');
                }
                else
                {
                    inQoutedString = false;
                }
            }
            else
            {
                fieldBuilder.Append(readChar);
            }
        }
        else
        {
            fieldBuilder.Append(readChar);
        }
    }
    record.Add(fieldBuilder.ToString().TrimEnd());
    records.Add(record);

    return records;
}

মনে রাখবেন যে এটি ক্ষেত্রগুলির প্রান্তের কেসটি ডাবল কোট দ্বারা সীমাবদ্ধ নয়, তবে মেরিলির ভিতরে একটি উদ্ধৃত স্ট্রিং রয়েছে handle কিছুটা আরও ভাল সম্প্রসারণের পাশাপাশি কিছু সঠিক লাইব্রেরির লিঙ্কগুলির জন্য এই পোস্টটি দেখুন ।


9

আমি @ সাথে একমত NotMyselfফাইলহেলপার্স ভালভাবে পরীক্ষিত এবং প্রকারের সমস্ত ধরণের কেসগুলি পরিচালনা করে যা আপনি নিজেই যদি করেন তবে শেষ পর্যন্ত আপনাকে মোকাবেলা করতে হবে। ফাইলহেল্পাররা কী করে তা একবার দেখুন এবং কেবল আপনার নিজের লিখুন যদি আপনি একেবারে নিশ্চিত হন যে (1) আপনার কখনও ফাইলহেল্পারদের প্রান্তের কেসগুলি পরিচালনা করার প্রয়োজন হবে না, বা (2) আপনি এই ধরণের স্টাফ লিখতে পছন্দ করেন এবং যাচ্ছেন আপনি যখন এই জাতীয় জিনিসগুলি বিশ্লেষণ করতে চান তখন আনন্দিত হন:

1, "বিল", "স্মিথ", "সুপারভাইজার", "কোনও মন্তব্য নেই"

2, 'ড্রেক,', 'ও'ম্যালি', "জানিটর,

উফফ, আমার উদ্ধৃতি নেই এবং আমি একটি নতুন লাইনে আছি!


6

আমি বিরক্ত হয়ে পড়েছিলাম তাই আমি আমার কিছু জিনিস সংশোধন করেছি। এটি একটি ওও পদ্ধতিতে পার্সিংকে ফাইলের মাধ্যমে পুনরাবৃত্তির পরিমাণ হ্রাস করার চেষ্টা করে, এটি শীর্ষের অগ্রভাগে কেবল একবারে পুনরাবৃত্তি করে।

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.IO;

namespace ConsoleApplication1
{
    class Program
    {

        static void Main(string[] args)
        {

            // usage:

            // note this wont run as getting streams is not Implemented

            // but will get you started

            CSVFileParser fileParser = new CSVFileParser();

            // TO Do:  configure fileparser

            PersonParser personParser = new PersonParser(fileParser);

            List<Person> persons = new List<Person>();
            // if the file is large and there is a good way to limit
            // without having to reparse the whole file you can use a 
            // linq query if you desire
            foreach (Person person in personParser.GetPersons())
            {
                persons.Add(person);
            }

            // now we have a list of Person objects
        }
    }

    public abstract  class CSVParser 
    {

        protected String[] deliniators = { "," };

        protected internal IEnumerable<String[]> GetRecords()
        {

            Stream stream = GetStream();
            StreamReader reader = new StreamReader(stream);

            String[] aRecord;
            while (!reader.EndOfStream)
            {
                  aRecord = reader.ReadLine().Split(deliniators,
                   StringSplitOptions.None);

                yield return aRecord;
            }

        }

        protected abstract Stream GetStream(); 

    }

    public class CSVFileParser : CSVParser
    {
        // to do: add logic to get a stream from a file

        protected override Stream GetStream()
        {
            throw new NotImplementedException();
        } 
    }

    public class CSVWebParser : CSVParser
    {
        // to do: add logic to get a stream from a web request

        protected override Stream GetStream()
        {
            throw new NotImplementedException();
        }
    }

    public class Person
    {
        public String Name { get; set; }
        public String Address { get; set; }
        public DateTime DOB { get; set; }
    }

    public class PersonParser 
    {

        public PersonParser(CSVParser parser)
        {
            this.Parser = parser;
        }

        public CSVParser Parser { get; set; }

        public  IEnumerable<Person> GetPersons()
        {
            foreach (String[] record in this.Parser.GetRecords())
            {
                yield return new Person()
                {
                    Name = record[0],
                    Address = record[1],
                    DOB = DateTime.Parse(record[2]),
                };
            }
        }
    }
}


2

এটি করার একটি ভাল সহজ উপায় হ'ল ফাইলটি খোলার জন্য এবং প্রতিটি লাইনকে একটি অ্যারে, লিঙ্কযুক্ত তালিকায়, আপনার পছন্দমতো ডেটা-স্ট্রাকচার-এর-মতো করে পড়া। যদিও প্রথম লাইনটি পরিচালনা করার বিষয়ে সতর্কতা অবলম্বন করুন।

এটি আপনার মাথার উপরে থাকতে পারে তবে সংযোগের স্ট্রিং ব্যবহার করে এগুলি অ্যাক্সেস করার সরাসরি উপায় রয়েছে বলে মনে হয় ।

সি # বা ভিবি এর পরিবর্তে পাইথন ব্যবহারের চেষ্টা করবেন না কেন? এটি আমদানি করার জন্য একটি দুর্দান্ত সিএসভি মডিউল রয়েছে যা আপনার জন্য সমস্ত ভারী উত্তোলন করে।


1
কোনও সিএসভি পার্সারের পক্ষে ভিবি থেকে পাইথনে লাফিয়ে পড়বেন না। ভিবিতে একটি আছে। যদিও অদ্ভুতভাবে মনে হয় এটি এই প্রশ্নের উত্তরে উপেক্ষা করা হয়েছে। msdn.microsoft.com/en-us/library/…
মার্কজে

1

আমাকে এই গ্রীষ্মে গ্রীষ্মের জন্য একটি প্রকল্পের জন্য .NET এ একটি সিএসভি পার্সার ব্যবহার করতে হয়েছিল এবং মাইক্রোসফ্ট জেট টেক্সট ড্রাইভারের সাথে স্থির হয়েছিলেন। আপনি একটি সংযোগ স্ট্রিং ব্যবহার করে একটি ফোল্ডার নির্দিষ্ট করেন, তারপরে একটি এসকিউএল নির্বাচন বিবৃতি ব্যবহার করে কোনও ফাইলকে জিজ্ঞাসা করুন। আপনি একটি স্কিমা.আইএনআই ফাইল ব্যবহার করে শক্তিশালী প্রকারগুলি নির্দিষ্ট করতে পারেন। আমি প্রথমে এটি করিনি, তবে তারপরে আমি খারাপ ফলাফল পাচ্ছিলাম যেখানে আইপি নম্বর বা "এক্সওয়াইকিউ 3.9 এসপি 1" এর মতো একটি এন্ট্রি যেমন ডেটার ধরণটি তত্ক্ষণাত্ প্রকাশিত হয়নি।

আমি যে সীমাবদ্ধতার মধ্যে পড়েছিলাম তা হ'ল এটি কলামের names৪ টি অক্ষরের নাম পরিচালনা করতে পারে না; এটি কেটে যায়। আমি খুব খারাপভাবে ডিজাইন করা ইনপুট ডেটা নিয়ে কাজ করছি, এ ছাড়া এটি কোনও সমস্যা হবেনা। এটি একটি ADO.NET ডেটাসেট প্রদান করে।

এটিই আমি খুঁজে পেল সেরা সমাধান। আমি আমার নিজের সিএসভি পার্সার রোলিংয়ের বিষয়ে সতর্ক থাকব, যেহেতু আমি সম্ভবত শেষের কয়েকটিটি মিস করব এবং আমি নেট খুঁজে বের করার জন্য অন্য কোনও ফ্রি সিএসভি পার্সিং প্যাকেজ পাইনি।

সম্পাদনা: এছাড়াও, প্রতি ডিরেক্টরি প্রতি কেবল একটি স্কিমা.ইএনআই ফাইল থাকতে পারে, তাই আমি প্রয়োজনীয় কলামগুলি দৃ strongly়ভাবে টাইপ করার জন্য এটিতে গতিশীলভাবে যুক্ত করেছিলাম। এটি নির্দিষ্ট করা কলামগুলিকে কেবল দৃ strongly়-টাইপ করবে এবং কোনও অনির্দিষ্ট ক্ষেত্রের জন্য অনুমান করবে। আমি সত্যিই এটির প্রশংসা করেছি, যেহেতু আমি একটি তরল 70+ কলাম সিএসভি আমদানির বিষয়ে কাজ করছি এবং প্রতিটি কলামটি কেবলমাত্র দুর্ব্যবহারকে নির্দিষ্ট করতে চাইনি।


কেন ভিএস.এন.টি সিএসভি পার্সারে অন্তর্নির্মিত নয়? msdn.microsoft.com/en-us/library/…
মার্কজে

1

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

    enum quotestatus
    {
        none,
        firstquote,
        secondquote
    }
    public static System.Collections.ArrayList Parse(string line,string delimiter)
    {        
        System.Collections.ArrayList ar = new System.Collections.ArrayList();
        StringBuilder field = new StringBuilder();
        quotestatus status = quotestatus.none;
        foreach (char ch in line.ToCharArray())
        {                                
            string chOmsch = "char";
            if (ch == Convert.ToChar(delimiter))
            {
                if (status== quotestatus.firstquote)
                {
                    chOmsch = "char";
                }                         
                else
                {
                    chOmsch = "delimiter";                    
                }                    
            }

            if (ch == Convert.ToChar(34))
            {
                chOmsch = "quotes";           
                if (status == quotestatus.firstquote)
                {
                    status = quotestatus.secondquote;
                }
                if (status == quotestatus.none )
                {
                    status = quotestatus.firstquote;
                }
            }

            switch (chOmsch)
            {
                case "char":
                    field.Append(ch);
                    break;
                case "delimiter":                        
                    ar.Add(field.ToString());
                    field.Clear();
                    break;
                case "quotes":
                    if (status==quotestatus.firstquote)
                    {
                        field.Clear();                            
                    }
                    if (status== quotestatus.secondquote)
                    {                                                                           
                            status =quotestatus.none;                                
                    }                    
                    break;
            }
        }
        if (field.Length != 0)            
        {
            ar.Add(field.ToString());                
        }           
        return ar;
    }

0

আপনি যদি গ্যারান্টি দিতে পারেন যে ডেটাতে কোনও কমা নেই, তবে সবচেয়ে সহজ উপায় সম্ভবত স্ট্রিং.স্প্লিট ব্যবহার করা হবে ।

উদাহরণ স্বরূপ:

String[] values = myString.Split(',');
myObject.StringField = values[0];
myObject.IntField = Int32.Parse(values[1]);

আপনি সাহায্যের জন্য ব্যবহার করতে পারেন এমন গ্রন্থাগার থাকতে পারে, তবে এটি সম্ভবত আপনি যতটা সহজ পেতে পারেন। কেবলমাত্র আপনার ডেটাতে কমা থাকতে পারে তা নিশ্চিত করুন, অন্যথায় আপনার আরও ভাল পার্স করা দরকার।


এটি সর্বোত্তম সমাধান নয়
রাউন্ডক্রিসিস

মেমরির ব্যবহার এবং প্রচুর ওভারহেডের উপর খুব খারাপ। ছোট কিছু কিলোবাইট কম হওয়া উচিত। অবশ্যই 10 এমবি সিএসভির জন্য ভাল নয়!
পাইটর কুলা

এটি আপনার মেমরির আকার এবং ফাইলের উপর নির্ভর করে।
টানামিয়াও
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.