//调用方法
public class FileObject

public static Encoding GetFileEncoding(string fileName)
        {
            Encoding encode = Encoding.Default;
            Common.IdentifyEncoding sinodetector;
            sinodetector = new Common.IdentifyEncoding();
            FileInfo finfo = new FileInfo(fileName);

            encode = sinodetector.GetEncoding(sinodetector.GetEncodingName(finfo));
            return encode;
        }

    Encoding curEncode = Common.FileObject.GetFileEncoding(bomFile.FileLocation);

    CsvReader csvReader = new CsvReader(backupFile, curEncode);
                DataTable dt = csvReader.ReadIntoDataTable();

//CSV Reader代码
using
System; using System.Collections.Generic; using System.Data; using System.IO; using System.Text; namespace Common { /// <summary> /// Class to read csv content from various sources /// </summary> public sealed class CsvReader : IDisposable { #region Members private FileStream _fileStream; private Stream _stream; private StreamReader _streamReader; private StreamWriter _streamWriter; private Stream _memoryStream; private Encoding _encoding; private readonly StringBuilder _columnBuilder = new StringBuilder(100); private readonly Type _type = Type.File; #endregion Members #region Properties /// <summary> /// Gets or sets whether column values should be trimmed /// </summary> private bool _TrimColumns; public bool TrimColumns { get { return _TrimColumns; } set { _TrimColumns = value; } } /// <summary> /// Gets or sets whether the csv file has a header row /// </summary> private bool _HasHeaderRow; public bool HasHeaderRow { get { return _HasHeaderRow; } set { _HasHeaderRow = value; } } /// <summary> /// Returns a collection of fields or null if no record has been read /// </summary> private List<string> _Fields; public List<string> Fields { get { return _Fields; } set { _Fields = value; } } /// <summary> /// Gets the field count or returns null if no fields have been read /// </summary> public int? FieldCount { get { return (Fields != null ? Fields.Count : (int?)null); } } #endregion Properties #region Enums /// <summary> /// Type enum /// </summary> private enum Type { File, Stream, String } #endregion Enums #region Constructors /// <summary> /// Initialises the reader to work from a file /// </summary> /// <param name="filePath">File path</param> public CsvReader(string filePath) { _type = Type.File; Initialise(filePath, Encoding.Default); } /// <summary> /// Initialises the reader to work from a file /// </summary> /// <param name="filePath">File path</param> /// <param name="encoding">Encoding</param> public CsvReader(string filePath, Encoding encoding) { _type = Type.File; Initialise(filePath, encoding); } /// <summary> /// Initialises the reader to work from an existing stream /// </summary> /// <param name="stream">Stream</param> public CsvReader(Stream stream) { _type = Type.Stream; Initialise(stream, Encoding.Default); } /// <summary> /// Initialises the reader to work from an existing stream /// </summary> /// <param name="stream">Stream</param> /// <param name="encoding">Encoding</param> public CsvReader(Stream stream, Encoding encoding) { _type = Type.Stream; Initialise(stream, encoding); } /// <summary> /// Initialises the reader to work from a csv string /// </summary> /// <param name="encoding"></param> /// <param name="csvContent"></param> public CsvReader(Encoding encoding, string csvContent) { _type = Type.String; Initialise(encoding, csvContent); } #endregion Constructors #region Methods /// <summary> /// Initialises the class to use a file /// </summary> /// <param name="filePath"></param> /// <param name="encoding"></param> private void Initialise(string filePath, Encoding encoding) { if (!File.Exists(filePath)) throw new FileNotFoundException(string.Format("The file '{0}' does not exist.", filePath)); _fileStream = File.OpenRead(filePath); Initialise(_fileStream, encoding); } /// <summary> /// Initialises the class to use a stream /// </summary> /// <param name="stream"></param> /// <param name="encoding"></param> private void Initialise(Stream stream, Encoding encoding) { if (stream == null) throw new ArgumentNullException("The supplied stream is null."); _stream = stream; _stream.Position = 0; _encoding = (encoding ?? Encoding.Default); _streamReader = new StreamReader(_stream, _encoding); } /// <summary> /// Initialies the class to use a string /// </summary> /// <param name="encoding"></param> /// <param name="csvContent"></param> private void Initialise(Encoding encoding, string csvContent) { if (csvContent == null) throw new ArgumentNullException("The supplied csvContent is null."); _encoding = (encoding ?? Encoding.Default); _memoryStream = new MemoryStream(csvContent.Length); _streamWriter = new StreamWriter(_memoryStream); _streamWriter.Write(csvContent); _streamWriter.Flush(); Initialise(_memoryStream, encoding); } /// <summary> /// Reads the next record /// </summary> /// <returns>True if a record was successfuly read, otherwise false</returns> public bool ReadNextRecord() { Fields = null; string line = _streamReader.ReadLine(); if (line == null) return false; ParseLine(line); return true; } /// <summary> /// Reads a csv file format into a data table. This method /// will always assume that the table has a header row as this will be used /// to determine the columns. /// </summary> /// <returns></returns> public DataTable ReadIntoDataTable() { return ReadIntoDataTable(new System.Type[] {}); } /// <summary> /// Reads a csv file format into a data table. This method /// will always assume that the table has a header row as this will be used /// to determine the columns. /// </summary> /// <param name="columnTypes">Array of column types</param> /// <returns></returns> public DataTable ReadIntoDataTable(System.Type[] columnTypes) { DataTable dataTable = new DataTable(); bool addedHeader = false; _stream.Position = 0; while (ReadNextRecord()) { if (!addedHeader) { for (int i = 0; i < Fields.Count; i++) dataTable.Columns.Add(Fields[i], (columnTypes.Length > 0 ? columnTypes[i] : typeof(string))); addedHeader = true; continue; } DataRow row = dataTable.NewRow(); for (int i = 0; i < Fields.Count; i++) row[i] = Fields[i]; dataTable.Rows.Add(row); } return dataTable; } /// <summary> /// Parses a csv line /// </summary> /// <param name="line">Line</param> private void ParseLine(string line) { Fields = new List<string>(); bool inColumn = false; bool inQuotes = false; _columnBuilder.Remove(0, _columnBuilder.Length); // Iterate through every character in the line for (int i = 0; i < line.Length; i++) { char character = line[i]; // If we are not currently inside a column if (!inColumn) { // If the current character is a double quote then the column value is contained within // double quotes, otherwise append the next character /* if (character == '"') inQuotes = true; else _columnBuilder.Append(character); inColumn = true; continue; * */ if (character == '"') { inQuotes = true; inColumn = true; continue; } else if (character == ',' && (0 < (i - 1) && line[i - 1] == ',')) { inColumn = false; } else { _columnBuilder.Append(character); inColumn = true; continue; } } // If we are in between double quotes if (inQuotes) { // If the current character is a double quote and the next character is a comma or we are at the end of the line // we are now no longer within the column. // Otherwise increment the loop counter as we are looking at an escaped double quote e.g. "" within a column if (character == '"' && ((line.Length > (i + 1) && line[i + 1] == ',') || ((i + 1) == line.Length))) { inQuotes = false; inColumn = false; i++; } else if (character == '"' && line.Length > (i + 1) && line[i + 1] == '"') i++; } else if (character == ',') inColumn = false; // If we are no longer in the column clear the builder and add the columns to the list if (!inColumn) { Fields.Add(TrimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString()); _columnBuilder.Remove(0, _columnBuilder.Length); } else // append the current column _columnBuilder.Append(character); } // If we are still inside a column add a new one if (inColumn) Fields.Add(TrimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString()); } /// <summary> /// Disposes of all unmanaged resources /// </summary> public void Dispose() { if (_streamReader != null) { _streamReader.Close(); _streamReader.Dispose(); } if (_streamWriter != null) { _streamWriter.Close(); _streamWriter.Dispose(); } if (_memoryStream != null) { _memoryStream.Close(); _memoryStream.Dispose(); } if (_fileStream != null) { _fileStream.Close(); _fileStream.Dispose(); } if ((_type == Type.String || _type == Type.File) && _stream != null) { _stream.Close(); _stream.Dispose(); } } #endregion Methods } }

 

posted on 2013-04-03 18:23  Black Bean  阅读(206)  评论(0)    收藏  举报