예제 #1
0
파일: CsvLiner.cs 프로젝트: chjfth/trivials
        /// <summary>
        /// Save a list, or an array of, type-T objects to a file.
        /// </summary>
        /// <typeparam name="T">User's object type.</typeparam>
        /// <param name="list">An enumerable object providing CSV data source.</param>
        /// <param name="csvpath">Path to a csv file.</param>
        /// <param name="hc">See comments of enum HeaderCare.</param>
        /// <param name="encoding">Text file encoding of the csv.</param>
        /// <returns>CSV data lines written, not including the header line.</returns>
        public static int SaveCsvFile <T>(IEnumerable <T> list, string csvpath,
                                          HeaderCare hc     = HeaderCare.None,
                                          Encoding encoding = null)
            where T : class, new()
        {
            int count = 0;

            if (encoding == null)
            {
                encoding = System.Text.Encoding.Default;
            }

            string correct_header_line = CsvLiner <T> .HeaderLine();

            using (StreamWriter textwriter = new StreamWriter(csvpath, false, encoding))
            {
                if ((hc & HeaderCare.Preserve) != 0)
                {
                    textwriter.WriteLine(correct_header_line);
                }

                foreach (T tobj in list)
                {
                    textwriter.WriteLine(CsvLiner <T> .Put(tobj));
                    count++;
                }
            }             // using file

            return(count);
        }
예제 #2
0
파일: Program.cs 프로젝트: chjfth/trivials
        /// <summary>
        /// Demo code.
        /// You see, we can use natural C# obj.field syntax to access each CSV field,
        /// no need to touch any ugly/verbose/redundant number for csv column index.
        /// What a breeze!
        /// </summary>
        static void Demo_CsvLiner()
        {
            string headerline = CsvLiner <CRecord> .HeaderLine();

            Console.WriteLine(headerline);

            CsvLiner <CRecord> .VerifyHeaderLine("FOOD,PRICE,QTY");

            string  csvinput1 = "Apple,1.5,100";
            CRecord rec1      = CsvLiner <CRecord> .Get(csvinput1);

            string csvoutput1 = CsvLiner <CRecord> .Put(rec1);

            if (csvoutput1 == csvinput1)
            {
                Console.WriteLine(rec1.FOOD);
                Console.WriteLine(rec1.PRICE);
                Console.WriteLine(rec1.QTY);

                Console.WriteLine("OK. Match.");
            }

            string[] strcols = { "QTY", "PRICE", "FOOD" };
            int[]    idxcols = CsvLiner <CRecord> .Idx(strcols);

            Debug.Assert(idxcols[0] == 2 && idxcols[1] == 1 && idxcols[2] == 0);

            // If you are a freak insisting on existing symbols...
            string[] strcols2 = new string[]
            {
                CsvLiner <CRecord> .uso.QTY,
                CsvLiner <CRecord> .uso.PRICE,
                CsvLiner <CRecord> .uso.FOOD,
            };
            int[] idxcols2 = CsvLiner <CRecord> .Idx(strcols2);

            Debug.Assert(idxcols2[0] == 2 && idxcols2[1] == 1 && idxcols2[2] == 0);

            CRecord r2 = CsvLiner <CRecord> .Get("10,Pear", new int[] { 2, 0 });

            Debug.Assert(r2.FOOD == "Pear" && r2.PRICE == "" && r2.QTY == "10");

            string s2 = CsvLiner <CRecord> .Put(r2, new int[] { 2, 0 });

            Debug.Assert(s2 == "10,Pear");

            //
            // Simplify typing a bit like this:
            //

            var      cc         = new CsvLiner <CRecordB>();
            CRecordB rec2       = cc.get(csvinput1);
            string   csvoutput2 = cc.put(rec2);

            Debug.Assert(csvoutput2 == csvinput1);

            Debug.Assert(cc.headerLine == headerline);
            Debug.Assert(cc.columns == CsvLiner <CRecord> .Columns());
        }
예제 #3
0
파일: CsvLiner.cs 프로젝트: chjfth/trivials
        /// <summary>
        /// Load a csv file and return an iterator of objects of user-given type(T).
        /// </summary>
        /// <typeparam name="T">User's object type.</typeparam>
        /// <param name="csvpath">Path to a csv file.</param>
        /// <param name="hc">See comments of enum HeaderCare.</param>
        /// <param name="encoding">Text file encoding of the csv.</param>
        /// <returns></returns>
        public static IEnumerable <T> LoadCsvFile <T>(string csvpath,
                                                      HeaderCare hc     = HeaderCare.None,
                                                      Encoding encoding = null)
            where T : class, new()
        {
            if (encoding == null)
            {
                encoding = System.Text.Encoding.Default;
            }

            string correct_header_line = CsvLiner <T> .HeaderLine();

            var csvlines = File.ReadLines(csvpath, encoding);

            using (var enumer = csvlines.GetEnumerator())
            {
                if (!enumer.MoveNext())
                {
                    yield break;
                }

                string line0 = enumer.Current;

                bool is_line0_header = (line0 == correct_header_line) ? true : false;

                if ((hc & HeaderCare.Verify) != 0)
                {
                    // Need verify CSV header
                    if (!is_line0_header)
                    {
                        string s = $"CSV file does not have required headerline.\r\n" +
                                   $"CSV file:\r\n" +
                                   $"  {csvpath}\r\n" +
                                   $"Required header line:\r\n" +
                                   $"  {correct_header_line}\r\n";
                        throw new CsvLinerException(s);
                    }
                }

                if ((hc & HeaderCare.Preserve) != 0)                 // user want to preserve first line
                {
                    yield return(CsvLiner <T> .Get(line0));
                }

                if (!is_line0_header)                 // first line is not a csv header
                {
                    yield return(CsvLiner <T> .Get(line0));
                }

                while (enumer.MoveNext())
                {
                    yield return(CsvLiner <T> .Get(enumer.Current));
                }
            }             // using enumerator
        }
예제 #4
0
파일: CsvLiner.cs 프로젝트: chjfth/trivials
        /// <summary>
        /// Check whether inputline matches correct headerline. If not throw exception.
        /// </summary>
        /// <param name="inputline">the line to verify</param>
        /// <param name="selected_columns">Tells which columns to care. If null, verify all columns.</param>
        public static void VerifyHeaderLine(string inputline, int[] selected_columns = null)
        {
            string correct;

            if (selected_columns == null)
            {
                correct = CsvLiner <T> .HeaderLine();
            }
            else
            {
                correct = CsvLiner <T> .HeaderLine(selected_columns);
            }

            if (correct != inputline)
            {
                string s = $"VerifyHeaderLine() mismatch.\r\n" +
                           $"  Input :  {inputline}\r\n" +
                           $"  Correct: {correct}\r\n";
                throw new CsvLinerException(s);
            }
        }
예제 #5
0
파일: Program.cs 프로젝트: chjfth/trivials
        /// <summary>
        /// See CsvLinerException in action, when we pass wrong parameters.
        /// </summary>
        static void Demo_CsvLiner_Exception()
        {
            Console.Out.WriteLine("==== Demo_CsvLiner_Exception : ERecord1 ====");
            //
            try
            {
                string headerline = CsvLiner <ERecord1> .HeaderLine();

                Debug.Assert(false);
            }
            catch (CsvLinerException ex)
            {
                // Something undesired HERE! We hope to catch CsvLinerException, but in vain.
                Console.Out.WriteLine(ex.Message + "\r\n");
                Debug.Assert(false);
            }
            catch (TypeInitializationException ex)
            {
                // Actually, we got this:
                Console.Out.WriteLine("Oops! Got TypeInitializationException. \r\n" +
                                      "This means we give wrong CsvLiner type parameters at compile time.\r\n" +
                                      "So we must check InnerException to get CsvLinerException.");

                Type   inner_exctype = ex.InnerException.GetType();
                string inner_message = ex.InnerException.Message;
                Console.Out.WriteLine(inner_exctype.FullName);
                Console.Out.WriteLine(inner_message);
            }

            Console.Out.WriteLine("==== Demo_CsvLiner_Exception : ERecord2 ====");
            //
            try
            {
                string headerline = CsvLiner <ERecord2> .HeaderLine();

                Debug.Assert(false);
            }
            catch (TypeInitializationException ex)
            {
                Console.Out.WriteLine(ex.InnerException.Message);
            }

            Console.Out.WriteLine("==== Demo_CsvLiner_Exception : ERecord3 ====");
            //
            try
            {
                string headerline = CsvLiner <ERecord3> .HeaderLine();

                Debug.Assert(false);
            }
            catch (TypeInitializationException ex)
            {
                Console.WriteLine(ex.InnerException.Message);
            }

            Console.Out.WriteLine("==== Demo_CsvLiner_Exception : Too many input columns ====");
            //
            try
            {
                CRecord rec = CsvLiner <CRecord> .Get("Apple,1.5,100,XYZ");

                Debug.Assert(false);
            }
            catch (CsvLinerException ex)
            {
                Console.WriteLine(ex.Message);
            }

            Console.Out.WriteLine("==== Demo_CsvLiner_Exception : Invalid column name ====");
            //
            try
            {
                int[] idxcols = CsvLiner <CRecord> .Idx(new string[] { "QTY", "PriZe" });

                Debug.Assert(false);
            }
            catch (CsvLinerException ex)
            {
                Console.WriteLine(ex.Message);
            }

            try
            {
                CsvLiner <CRecord> .VerifyHeaderLine("--FOOD,PRICE,QTY--");

                Debug.Assert(false);
            }
            catch (CsvLinerException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }