TextFieldParser equivalent in .NET?

后端 未结 2 1849
故里飘歌
故里飘歌 2020-12-17 08:29

Is there a modern .NET equivalent to the TextFieldParser class in VB6? Performance is a lot lower than a simple String.Split()

相关标签:
2条回答
  • 2020-12-17 08:44

    This is my solution:

    public class TextFieldParser
        {
            enum FieldType { FixedWidth, Delimited };
    
            public enum CompleteElements 
            {
                /// <summary>
                /// Returns as many elements as fileWidths input be
                /// </summary>
                AllElements, 
                /// <summary>
                /// Only returns elements who have not null values
                /// </summary>
                OnlyValues 
            };
    
            int[] m_fieldWidths;
            string m_line;
            List<string> m_results;
            int m_lineWidth;
            public CompleteElements m_CompleteElements;
    
            public TextFieldParser(string line)
            {
                m_line = line;
                m_lineWidth = m_line.Length;
                m_results = new List<string>();
                m_CompleteElements = CompleteElements.OnlyValues;
            }
    
            public void SetCompleteElements(CompleteElements value) 
            {
                m_CompleteElements = value;
            }
    
            public void SetFieldWidths(params int[] fileWidths)
            {
                m_fieldWidths = fileWidths;
            }
    
            public string[] ReadFields()
            {
                int pivot = 0;
                m_results = new List<string>();
    
                for (int x = 0; x < m_fieldWidths.Length; x++) 
                {
                    if(pivot + m_fieldWidths[x] <= m_lineWidth)
                    {
                        m_results.Add(m_line.Substring(pivot, m_fieldWidths[x]));                    
                    }
                    else
                    {
                        if (m_CompleteElements == CompleteElements.AllElements) 
                        {
                            m_results.Add(null);
                        }
    
                        break;
                    }
                    pivot += m_fieldWidths[x];
                }
                return m_results.ToArray();
            }
        }
    

    A simple session:

    string line = "1234567890123456789012345678890";
    TextFieldParser parser = new TextFieldParser(line);
    parser.SetFieldWidths(1, 2, 3, 4, 5, 6, 7, 8);
    
    string[] resultOnlyValues = parser.ReadFields();
    /*
    results:
    resultOnlyValues[0] : "1"
    resultOnlyValues[1] : "23"
    resultOnlyValues[2] : "456"
    resultOnlyValues[3] : "7890"
    resultOnlyValues[4] : "12345"
    resultOnlyValues[5] : "678901"
    resultOnlyValues[6] : "2345678"
    */
    parser.SetCompleteElements(TextFieldParser.CompleteElements.AllElements);
    string[] resultAllElement = parser.ReadFields();
    /*
    results:
    resultAllElement[0] : "1"
    resultAllElement[1] : "23"
    resultAllElement[2] : "456"
    resultAllElement[3] : "7890"
    resultAllElement[4] : "12345"
    resultAllElement[5] : "678901"
    resultAllElement[6] : "2345678"
    resultAllElement[7] : null
    */
    
    0 讨论(0)
  • 2020-12-17 08:46

    I have compared performance with that code: https://gist.github.com/Ruszrok/7861319

    I used an input file with about 1 000 000 records separated with spaces. I tried five experiments.

    • String.Split avg time: 291 ms
    • Microsoft.VisualBasic.FileIO.TextFieldParser avg time: 15843 ms

    You can use the Microsoft.VisualBasic.FileIO.TextFieldParser class. Reference Microsoft.VisualBasic. Sample in gist.

    0 讨论(0)
提交回复
热议问题