Привет, может кому понадобится
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>>