[C#]CsvReader & CsvWriter
От: 0rc Украина  
Дата: 29.03.05 12:32
Оценка:
Привет, может кому понадобится

CsvReadWriter.cs
using System;
using System.Text;
using System.IO;
using System.Collections;

namespace orc.IO
{
    internal interface CsvAbstract
    {
        char Delimiter { get ; set; }
        void Close();
    }
    /// <summary>
    /// 
    /// </summary>
    public class CsvWriter : CsvAbstract, System.IDisposable 
    {
        TextWriter _w;
        char _colDelim;
        public CsvWriter(TextWriter stm)
        {
            _w = stm;
            _colDelim = ',';
        }

        public CsvWriter(string stm, bool append, Encoding encoding)
        {
            _w = new StreamWriter(stm, append, encoding);
            _colDelim = ',';
        }

        public void WriteLine(string line)
        {
            _w.WriteLine( line );
        }

        public void WriteArray(object[] values)
        {
            string line  = "";
            foreach(object i in values)
            {
                string value = i.ToString();
                if(value.IndexOfAny(new char[]{',','\"'}) != -1)
                {
                    value = value.Replace("\"","\"\"");
                    value =  '\"' + value + '\"';
                }
                line += (line.Length==0) ? value : _colDelim +value;
            }

            if(line.Length != 0)
                _w.WriteLine( line );
        }
    
        #region CsvAbstract Members

        public char Delimiter {     get { return _colDelim; } set { _colDelim = value ; } }
        public void Close()     {    _w.Close(); }

        #endregion
    
        #region IDisposable Members

        public void Dispose()
        {
            Close();
            GC.SuppressFinalize(this);
        }

        #endregion
    }

    public class CsvReader : CsvAbstract
    {
        TextReader _r;
        char[] _buffer;
        int _pos;
        int _used;

        // assumes end of record delimiter is {CR}{LF}, {CR}, or {LF}
        // possible values are {CR}{LF}, {CR}, {LF}, ';', ',', '\t'
        // char _recDelim;

        char _colDelim; // possible values ',', ';', '\t', '|'
        char _quoteChar;

        ArrayList _values;
        int _fields;

        public CsvReader(Uri location, string proxy, int bufsize) 
        {  // the location of the .csv file
            _r = new StreamReader(location.LocalPath, true);
                        
            _buffer = new char[bufsize];
            _values = new ArrayList();
        }

        public CsvReader(Stream stm, int bufsize) 
        {  // the location of the .csv file
            _r = new StreamReader(stm, true);
            _buffer = new char[bufsize];
            _values = new ArrayList();
        }     
        public CsvReader(TextReader stm, int bufsize) 
        {  // the location of the .csv file
            _r = stm;
            _buffer = new char[bufsize];
            _values = new ArrayList();
        }     

        public TextReader Reader 
        {
            get { return _r; }
        }

        const int EOF = 0xffff;

        public bool Read() 
        { // read a record.
            _fields = 0;
            char ch = ReadChar();
            if (ch == 0) return false;
            while (ch != 0 && ch == '\r' || ch == '\n' || ch == ' ') 
                ch = ReadChar();
            if (ch == 0) return false;

            while (ch != 0 && ch != '\r' && ch != '\n') 
            {
                StringBuilder sb = AddField();
                if (ch == '\'' || ch == '"') 
                {
                    _quoteChar= ch;         
                    char c = ReadChar();
                    bool done = false;
                    while (!done && c != 0) 
                    {
                        while (c != 0 && c != ch) 
                        { // scan literal.
                            sb.Append(c);
                            c = ReadChar();
                        }
                        if (c == ch) 
                        {
                            done = true;
                            char next = ReadChar(); // consume end quote
                            if (next == ch ) 
                            {
                                // it was an escaped quote sequence "" inside the literal
                                // so append a single " and consume the second end quote.
                                done = false;
                                sb.Append(next);
                                c = ReadChar();
                            } 
                            else if (_colDelim != 0 && next != _colDelim && next != 0 && next != '\n' && next != '\r') 
                            {
                                // it was an un-escaped quote embedded inside a string literal
                                // in this case the quote is probably just part of the text so ignore it.
                                done = false;
                                sb.Append(c);
                                sb.Append(next);
                                c = ReadChar();
                            } 
                            else 
                            {
                                c = next;
                            }
                        }
                    }
                    ch = c;         
                } 
                else 
                {        
                    // scan number, date, time, float, etc.
                    while (ch != 0 && ch != '\n' && ch != '\r') 
                    {
                        if (ch == _colDelim || (_colDelim == '\0' && (ch == ',' || ch == ';' || ch == '\t' || ch == '|')))
                            break;
                        sb.Append(ch);
                        ch = ReadChar();
                    }
                } 
                if (ch == _colDelim || (_colDelim == '\0' && (ch == ',' || ch == ';' || ch == '\t' || ch == '|')))
                {
                    _colDelim = ch;
                    ch = ReadChar();
                    if (ch == '\n' || ch == '\r') 
                    {
                        sb=AddField(); // blank field.
                    }
                }
            }
            return true;
        }

        public char QuoteChar { get { return _quoteChar; } }
        public char Delimiter { get { return _colDelim; } set { _colDelim = value ; }}

        public int FieldCount { get { return _fields; } }

        public string this[int i] { get { return ((StringBuilder)_values[i]).ToString(); } }

        char ReadChar() 
        {
            if (_pos == _used) 
            {
                _pos = 0;
                _used = _r.Read(_buffer, 0, _buffer.Length);
            }
            if (_pos == _used) 
            {
                return (char)0;
            }
            return _buffer[_pos++];
        }

        StringBuilder AddField() 
        {
            if (_fields == _values.Count) 
            {
                _values.Add(new StringBuilder());
            }
            StringBuilder sb = (StringBuilder)_values[_fields++];
            sb.Length = 0;
            return sb;
        }

        public void Close() 
        {
            _r.Close();
        }
        public string[] Values
        {
            get
            {
                string[] vector = new string[FieldCount];
                for(int i = 0 ; i < FieldCount ; i++)
                {
                    vector[i] = this[i];        

                }
                return vector;
            }
        }
    }

}
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.