CSV是一種十分簡潔的數據結構,在DOTNET平台實際使用中發現微軟官方並沒有提供默認的方法,而網上好多例子發現實現並不嚴謹甚至一些含有明顯錯誤,所以后面自己實現了一個讀寫工具類,這里發出來希望方便后面朋友(難免還是會有考慮不到的地方,可隨時郵件聯系)
使用該工具可對csv文件進行讀寫(甚至不用去了解CSV的各種規范)
直接以List<List<string>> 形式輸出,方便進一步處理
因為工具類需要讀取文件資源讀取完畢后如果確認不會再次讀取,建議立即Dispose,以釋放文件句柄(寫入使用該類的靜態資源,Dispose不會對其有影響)
讀
CsvFileHelper myCsv = new CsvFileHelper(@"C:\Users\administer\Desktop\my6.csv", Encoding.UTF8); var myData = myCsv.GetListCsvData(); //其他的操作 myCsv.Dispose();
寫
CsvFileHelper.SaveCsvFile(@"C:\Users\administer\Desktop\my9.csv", myData, true, new System.Text.UTF8Encoding(false));
單個元素支持包括tab,換行回車(\r\n),空內容等在內的所有文本字符 (在使用時請確定文件的編碼方式)
可指定元素分割符,行分隔符官方必須為\r\n(\r\n可以作為內容出現在元素中),轉義字符必須為".
轉義所有的引號必須出現在首尾(如果不在首尾,則不會按轉義符處理,直接作為引號處理)[excel可以讀取轉義出現在中間的情況,而本身存儲不會使用這種方式,保存時並會強制修復這種異常,所以這里遇到中間轉義的情況直接拋出指定異常]
如果在被轉義的情況下需要出現引號,則使用2個引號代替(如果需要在首部使用雙引號,則需要轉義該元素,其他地方可直接使用)(excel對所有雙引號都進行轉義,無論其出現位置,對於保存方式可以選擇是否按excel的方式進行保存)
每一行的結尾是補需要逗號結束的,如果多加一個逗號則標識該行會多一個空元素
下面是有關CSV的介紹(若僅需要使用可忽略不用理會)
csv(Comma Separated Values)逗號分隔值,有時也稱為字符分隔值,因為分隔字符也可以不是逗號),其文件以純文本形式存儲表格數據(數字和文本)。純文本意味着該文件是一個字符序列,不含必須象二進制數字那樣被解讀的數據。CSV文件由任意數目的記錄組成,記錄間以某種換行符分隔;每條記錄由字段組成,字段間的分隔符是其它字符或字符串,最常見的是逗號或制表符。通常,所有記錄都有完全相同的字段序列。CSV是一種Excel表格的導出格式,在Excel表格的菜單欄中點擊文件->另存為會彈出一個文件夾瀏覽窗口,在下拉框中可以選擇保存格式,其中有一個就是.CSV(逗號分隔符)選項。
CSV是一種通用的、相對簡單的文件格式,被用戶、商業和科學廣泛應用。最廣泛的應用是在程序之間轉移表格數據。因為大量程序都支持某種CSV變體,至少是作為一種可選擇的輸入/輸出格式。例如,一個用戶可能需要交換信息,從一個以私有格式存儲數據的數據庫程序,到一個數據格式完全不同的電子表格。最可能的情況是,該數據庫程序可以導出數據為“CSV”,然后被導出的CSV文件可以被電子表格程序導入。
“CSV”並不是一種單一的、定義明確的格式(盡管RFC 4180有一個被通常使用的定義)。因此在實踐中,術語“CSV”泛指具有以下特征的任何文件:
純文本,使用某個字符集,比如ASCII、Unicode、EBCDIC或GB2312;
由記錄組成(典型的是每行一條記錄);
每條記錄被分隔符分隔為字段(典型分隔符有逗號、分號或制表符;有時分隔符可以包括可選的空格);
每條記錄都有同樣的字段序列。
在這些常規的約束條件下,存在着許多CSV變體,故CSV文件並不完全互通
逗號分隔列(CSL)是一種數據格式,起初在最古老的簡單電腦中被稱為逗號分隔值(CSV)。
CSL/CSV被用來作為簡單的數據庫。一些早期的軟件應用,比如文字處理器,允許一系列“變量數據”在兩個文件之間被合並:一個是模板文件,一個是包含姓名、地址和其它數據字段的CSL數據庫。許多應用程序仍然有這種能力。
逗號分隔列過去和現在都被用於在兩個不同架構的機器之間交換數據庫信息。純文本的CSV文件大幅避免了不兼容性,比如字節順序和字長。這些文件大部分是可讀的,所以在沒有完美的文檔或通訊的情況下仍然很容易處理。
最后附上工具類代碼如下:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace MyCommonHelper.FileHelper
{
/// <summary>
/// 單個元素支持包括tab,換行回車(\r\n),空內容等在內的所有文本字符 (在使用時請確定文件的編碼方式)
/// 可指定元素分割符,行非官方必須為\r\n(\r\n可以作為內容出現在元素中),轉義字符必須為".
/// 轉義所有的引號必須出現在首尾(如果不在首尾,則不會按轉義符處理,直接作為引號處理)[excel可以讀取轉義出現在中間的情況,
///而本身存儲不會使用這種方式,保存時並會強制修復這種異常,所以這里遇到中間轉義的情況直接拋出指定異常]
/// 如果在被轉義的情況下需要出現引號,則使用2個引號代替(如果需要在首部使用雙引號,則需要轉義該元素,其他地方可直接使用)
///(excel對所有雙引號都進行轉義,無論其出現位置,對於保存方式可以選擇是否按excel的方式進行保存)
/// 每一行的結尾是不需要逗號結束的,如果多加一個逗號則標識該行會多一個空元素
/// 空行也是一個空元素,一個逗號是2個空元素,所以不可能出現有的行元素為空
/// 使用問題或疑問可通過mycllq@hotmail.com進行聯系
/// </summary>
public sealed class CsvFileHelper : 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 Type _type = Type.File;
private bool _trimColumns = false;
private char _csvSeparator = ',';
#endregion Members
#region Properties
/// <summary>
/// Gets or sets whether column values should be trimmed
/// </summary>
public bool TrimColumns
{
get { return _trimColumns; }
set { _trimColumns = value; }
}
public Type DataSouceType
{
get{ return _type;}
}
/// <summary>
/// get or set Csv Separator (Default Values is ,)
/// </summary>
public char CsvSeparator
{
get { return _csvSeparator; }
set { _csvSeparator = value; }
}
#endregion Properties
#region Enums
/// <summary>
/// Type enum
/// </summary>
public enum Type
{
File,
Stream
}
#endregion Enums
#region Methods
/// <summary>
/// Initialises the reader to work from a file
/// </summary>
/// <param name="filePath">File path</param>
public CsvFileHelper(string filePath):this(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 CsvFileHelper(string filePath, Encoding encoding)
{
_type = Type.File;
if (!File.Exists(filePath))
{
throw new FileNotFoundException(string.Format("The file '{0}' does not exist.", filePath));
}
//_stream = File.OpenRead(filePath);
//return a FileStream (OpenRead 源碼就是 return new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);)
_stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
_stream.Position = 0;
_encoding = (encoding ?? Encoding.Default);
_streamReader = new StreamReader(_stream, _encoding);
}
/// <summary>
/// Initialises the reader to work from an existing stream
/// </summary>
/// <param name="stream">Stream</param>
public CsvFileHelper(Stream stream):this(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 CsvFileHelper(Stream stream, Encoding encoding)
{
_type = Type.Stream;
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>
/// Initialises the reader to work from an existing stream (with the Separator char)
/// </summary>
/// <param name="stream">Stream</param>
/// <param name="encoding">Encoding</param>
/// <param name="yourSeparator"> the Separator char</param>
public CsvFileHelper(Stream stream, Encoding encoding, char yourSeparator): this(stream, encoding)
{
CsvSeparator = yourSeparator;
}
private List<string> ParseLine(string line)
{
StringBuilder _columnBuilder = new StringBuilder();
List<string> Fields = new List<string>();
bool inColumn = false; //是否是在一個列元素里
bool inQuotes = false; //是否需要轉義
bool isNotEnd = 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
inColumn = true;
if (character == '"')
{
inQuotes = true;
continue;
}
}
// If we are in between double quotes
if (inQuotes)
{
if ((i + 1) == line.Length)//這個字符已經結束了整行
{
if (character == '"') //正常轉義結束,且該行已經結束
{
inQuotes = false;
continue; //當前字符不用添加,跳出后直結束后會添加該元素
}
else //異常結束,轉義未收尾
{
isNotEnd = true;
}
}
else if (character == '"' && line[i + 1] == _csvSeparator) //結束轉義,且后面有可能還有數據
{
inQuotes = false;
inColumn = false;
i++; //跳過下一個字符
}
else if (character == '"' && line[i + 1] == '"') //雙引號轉義
{
i++; //跳過下一個字符
}
else if (character == '"') //雙引號單獨出現(這種情況實際上已經是格式錯誤,為了兼容可暫時不處理)
{
throw new Exception(string.Format("[{0}]:格式錯誤,錯誤的雙引號轉義 near [{1}] ","ParseLine", line));
}
//其他情況直接跳出,后面正常添加
}
else if (character == _csvSeparator)
inColumn = false;
// If we are no longer in the column clear the builder and add the columns to the list
if (!inColumn) //結束該元素時inColumn置為false,並且不處理當前字符,直接進行Add
{
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 (標准格式一行結尾不需要逗號結尾,而上面for是遇到逗號才添加的,為了兼容最后還要添加一次)
if (inColumn)
{
if (isNotEnd)
{
_columnBuilder.Append("\r\n");
}
Fields.Add(TrimColumns ? _columnBuilder.ToString().Trim() : _columnBuilder.ToString());
}
//如果inColumn為false,說明已經添加,因為最后一個字符為分隔符,所以后面要加上一個空元素
//另外一種情況是line為""空行,(空行也是一個空元素,一個逗號是2個空元素),正好inColumn為默認值false,在此處添加一空元素
else
{
Fields.Add("");
}
return Fields;
}
/// <summary>
/// 處理未完成的Csv單行
/// </summary>
/// <param name="line">數據源</param>
/// <returns>元素列表</returns>
private List<string> ParseContinueLine(string line)
{
StringBuilder _columnBuilder = new StringBuilder();
List<string> Fields = new List<string>();
_columnBuilder.Remove(0, _columnBuilder.Length);
if (line == "")
{
Fields.Add("\r\n");
return Fields;
}
for (int i = 0; i < line.Length; i++)
{
char character = line[i];
if ((i + 1) == line.Length)//這個字符已經結束了整行
{
if (character == '"') //正常轉義結束,且該行已經結束
{
Fields.Add(TrimColumns ? _columnBuilder.ToString().TrimEnd() : _columnBuilder.ToString());
return Fields;
}
else //異常結束,轉義未收尾
{
_columnBuilder.Append("\r\n");
Fields.Add(_columnBuilder.ToString());
return Fields;
}
}
else if (character == '"' && line[i + 1] == _csvSeparator) //結束轉義,且后面有可能還有數據
{
Fields.Add(TrimColumns ? _columnBuilder.ToString().TrimEnd() : _columnBuilder.ToString());
i++; //跳過下一個字符
Fields.AddRange(ParseLine(line.Remove(0, i+1)));
break;
}
else if (character == '"' && line[i + 1] == '"') //雙引號轉義
{
i++; //跳過下一個字符
}
else if (character == '"') //雙引號單獨出現(這種情況實際上已經是格式錯誤,轉義用雙引號一定是【,"】【",】形式,
//包含在里面的雙引號需要使用一對雙引號進行轉義)
{
throw new Exception(string.Format("[{0}]:格式錯誤,錯誤的雙引號轉義 near [{1}]", "ParseContinueLine", line));
}
_columnBuilder.Append(character);
}
return Fields;
}
public List<List<string>> GetListCsvData()
{
_stream.Position = 0;
List<List<string>> tempListCsvData = new List<List<string>>();
bool isNotEndLine = false;
//這里的ReadLine可能把轉義的/r/n分割,需要后面單獨處理
string tempCsvRowString = _streamReader.ReadLine();
while (tempCsvRowString!=null)
{
List<string> tempCsvRowList;
if (isNotEndLine)
{
tempCsvRowList = ParseContinueLine(tempCsvRowString);
isNotEndLine = (tempCsvRowList.Count > 0 && tempCsvRowList[tempCsvRowList.Count - 1].EndsWith("\r\n"));
List<string> myNowContinueList = tempListCsvData[tempListCsvData.Count - 1];
myNowContinueList[myNowContinueList.Count - 1] += tempCsvRowList[0];
tempCsvRowList.RemoveAt(0);
myNowContinueList.AddRange(tempCsvRowList);
}
else
{
tempCsvRowList = ParseLine(tempCsvRowString);
isNotEndLine = (tempCsvRowList.Count > 0 && tempCsvRowList[tempCsvRowList.Count - 1].EndsWith("\r\n"));
tempListCsvData.Add(tempCsvRowList);
}
tempCsvRowString = _streamReader.ReadLine();
}
return tempListCsvData;
}
public void Dispose()
{
if(_streamReader!=null)
{
_streamReader.Dispose();
}
if(_stream!=null)
{
_stream.Dispose();
}
}
#endregion
#region StaticTool
#region 編碼方式可接受值
//請考慮讓應用程序使用 UTF-8 或 Unicode (UTF-16) 作為默認編碼。大多數其他編碼要么不完整並將許多字符轉換為“?”,
//要么在不同的平台上具有稍有不同的行為。非 Unicode 編碼通常具有多義性,應用程序則不再試圖確定合適的編碼,也不再提供用戶用來修復文本語言或編碼的更正下拉菜單。
/*
This code produces the following output.
CodePage identifier and name BrDisp BrSave MNDisp MNSave 1-Byte ReadOnly
37 IBM037 False False False False True True
437 IBM437 False False False False True True
500 IBM500 False False False False True True
708 ASMO-708 True True False False True True
720 DOS-720 True True False False True True
737 ibm737 False False False False True True
775 ibm775 False False False False True True
850 ibm850 False False False False True True
852 ibm852 True True False False True True
855 IBM855 False False False False True True
857 ibm857 False False False False True True
858 IBM00858 False False False False True True
860 IBM860 False False False False True True
861 ibm861 False False False False True True
862 DOS-862 True True False False True True
863 IBM863 False False False False True True
864 IBM864 False False False False True True
865 IBM865 False False False False True True
866 cp866 True True False False True True
869 ibm869 False False False False True True
870 IBM870 False False False False True True
874 windows-874 True True True True True True
875 cp875 False False False False True True
932 shift_jis True True True True False True
936 gb2312 True True True True False True
949 ks_c_5601-1987 True True True True False True
950 big5 True True True True False True
1026 IBM1026 False False False False True True
1047 IBM01047 False False False False True True
1140 IBM01140 False False False False True True
1141 IBM01141 False False False False True True
1142 IBM01142 False False False False True True
1143 IBM01143 False False False False True True
1144 IBM01144 False False False False True True
1145 IBM01145 False False False False True True
1146 IBM01146 False False False False True True
1147 IBM01147 False False False False True True
1148 IBM01148 False False False False True True
1149 IBM01149 False False False False True True
1200 utf-16 False True False False False True
1201 unicodeFFFE False False False False False True
1250 windows-1250 True True True True True True
1251 windows-1251 True True True True True True
1252 Windows-1252 True True True True True True
1253 windows-1253 True True True True True True
1254 windows-1254 True True True True True True
1255 windows-1255 True True True True True True
1256 windows-1256 True True True True True True
1257 windows-1257 True True True True True True
1258 windows-1258 True True True True True True
1361 Johab False False False False False True
10000 macintosh False False False False True True
10001 x-mac-japanese False False False False False True
10002 x-mac-chinesetrad False False False False False True
10003 x-mac-korean False False False False False True
10004 x-mac-arabic False False False False True True
10005 x-mac-hebrew False False False False True True
10006 x-mac-greek False False False False True True
10007 x-mac-cyrillic False False False False True True
10008 x-mac-chinesesimp False False False False False True
10010 x-mac-romanian False False False False True True
10017 x-mac-ukrainian False False False False True True
10021 x-mac-thai False False False False True True
10029 x-mac-ce False False False False True True
10079 x-mac-icelandic False False False False True True
10081 x-mac-turkish False False False False True True
10082 x-mac-croatian False False False False True True
20000 x-Chinese-CNS False False False False False True
20001 x-cp20001 False False False False False True
20002 x-Chinese-Eten False False False False False True
20003 x-cp20003 False False False False False True
20004 x-cp20004 False False False False False True
20005 x-cp20005 False False False False False True
20105 x-IA5 False False False False True True
20106 x-IA5-German False False False False True True
20107 x-IA5-Swedish False False False False True True
20108 x-IA5-Norwegian False False False False True True
20127 us-ascii False False True True True True
20261 x-cp20261 False False False False False True
20269 x-cp20269 False False False False True True
20273 IBM273 False False False False True True
20277 IBM277 False False False False True True
20278 IBM278 False False False False True True
20280 IBM280 False False False False True True
20284 IBM284 False False False False True True
20285 IBM285 False False False False True True
20290 IBM290 False False False False True True
20297 IBM297 False False False False True True
20420 IBM420 False False False False True True
20423 IBM423 False False False False True True
20424 IBM424 False False False False True True
20833 x-EBCDIC-KoreanExtended False False False False True True
20838 IBM-Thai False False False False True True
20866 koi8-r True True True True True True
20871 IBM871 False False False False True True
20880 IBM880 False False False False True True
20905 IBM905 False False False False True True
20924 IBM00924 False False False False True True
20932 EUC-JP False False False False False True
20936 x-cp20936 False False False False False True
20949 x-cp20949 False False False False False True
21025 cp1025 False False False False True True
21866 koi8-u True True True True True True
28591 iso-8859-1 True True True True True True
28592 iso-8859-2 True True True True True True
28593 iso-8859-3 False False True True True True
28594 iso-8859-4 True True True True True True
28595 iso-8859-5 True True True True True True
28596 iso-8859-6 True True True True True True
28597 iso-8859-7 True True True True True True
28598 iso-8859-8 True True False False True True
28599 iso-8859-9 True True True True True True
28603 iso-8859-13 False False False False True True
28605 iso-8859-15 False True True True True True
29001 x-Europa False False False False True True
38598 iso-8859-8-i True True True True True True
50220 iso-2022-jp False False True True False True
50221 csISO2022JP False True True True False True
50222 iso-2022-jp False False False False False True
50225 iso-2022-kr False False True False False True
50227 x-cp50227 False False False False False True
51932 euc-jp True True True True False True
51936 EUC-CN False False False False False True
51949 euc-kr False False True True False True
52936 hz-gb-2312 True True True True False True
54936 GB18030 True True True True False True
57002 x-iscii-de False False False False False True
57003 x-iscii-be False False False False False True
57004 x-iscii-ta False False False False False True
57005 x-iscii-te False False False False False True
57006 x-iscii-as False False False False False True
57007 x-iscii-or False False False False False True
57008 x-iscii-ka False False False False False True
57009 x-iscii-ma False False False False False True
57010 x-iscii-gu False False False False False True
57011 x-iscii-pa False False False False False True
65000 utf-7 False False True True False True
65001 utf-8 True True True True False True
65005 utf-32 False False False False False True
65006 utf-32BE False False False False False True
*/
#endregion
/// <summary>
/// 靜態構造函數只有在靜態方法將要使用的時候才進行調用(靜態成員同理)
/// </summary>
static CsvFileHelper()
{
isSaveAsExcel = true;
defaultEncoding = new System.Text.UTF8Encoding(false);
}
private static bool isSaveAsExcel ;
private static Encoding defaultEncoding;
private static char csvSeparator = ',';
//private static Encoding utfBom = System.Text.Encoding.GetEncoding("GB2312");
/// <summary>
/// get or set Csv Separator (Default Values is ,)
/// </summary>
public static char DefaultCsvSeparator
{
get { return csvSeparator; }
set { csvSeparator = value; }
}
/// <summary>
/// get or set if save as Excel type (出現在首部的“是必須轉義的,而出現在中間的不可以不用專門轉義,而excel對所有雙引號都進行轉義,無論其出現位置)
/// </summary>
public static bool IsSaveAsExcel
{
get { return isSaveAsExcel; }
set { isSaveAsExcel = value; }
}
/// <summary>
/// get or set Default Encoding (notice : if your want the System not with bom ,you should use the relevant Encoding)
/// </summary>
public static Encoding DefaultEncoding
{
get { return defaultEncoding; }
set { defaultEncoding = value; }
}
private static void WriteCsvVeiw(List<List<string>> yourListCsvData, TextWriter writer)
{
foreach(List<string> tempField in yourListCsvData)
{
WriteCsvLine(tempField, writer);
}
}
private static void WriteCsvLine(List<string> fields, TextWriter writer)
{
StringBuilder myStrBld = new StringBuilder();
//對於CSV數據來說不可能出現一行的數據元素的數量是0的情況,所以不用考慮fields.Count為0的情況(如果為0則為錯誤數據直接忽略)
//foreach(string tempField in fields) //使用foreach會產生許多不必要的string拷貝
for (int i = 0; i < fields.Count; i++)
{
//通過文件轉換出來的fields是不會為null的,為了兼容外部構建數據源,可能出現null的情況,這里強制轉換為""
if (fields[i] == null)
{
myStrBld.Append("");
}
else
{
bool quotesRequired =
(isSaveAsExcel ? (fields[i].Contains(csvSeparator) || fields[i].Contains("\r\n") || fields[i].Contains("\"")) :
(fields[i].Contains(csvSeparator) || fields[i].Contains("\r\n") || fields[i].StartsWith("\"")));
if (quotesRequired)
{
if (fields[i].Contains("\""))
{
myStrBld.Append(String.Format("\"{0}\"", fields[i].Replace("\"", "\"\"")));
}
else
{
myStrBld.Append(String.Format("\"{0}\"", fields[i]));
}
}
else
{
myStrBld.Append(fields[i]);
}
}
if (i < fields.Count - 1)
{
myStrBld.Append(csvSeparator);
}
}
writer.WriteLine(myStrBld.ToString());
}
public static void SaveCsvFile(string yourFilePath,List<List<string>> yourDataSouse,bool isAppend,Encoding yourEncode)
{
//FileStream myCsvStream = new FileStream(yourFilePath, FileMode.Create, FileAccess.ReadWrite);
if (isAppend && !File.Exists(yourFilePath))
{
throw new Exception("in Append mode the FilePath must exist");
}
if(!isAppend && !File.Exists(yourFilePath))
{
if (yourFilePath.Contains('\\'))
{
if (!Directory.Exists(yourFilePath.Remove(yourFilePath.LastIndexOf('\\'))))
{
throw new Exception("the FilePath or the Directory it not exist");
}
}
else
{
throw new Exception("find error in your FilePath");
}
}
//StreamWriter myCsvSw = new StreamWriter(yourFilePath, isAppend, yourEncode);
//isAppend對應的Stream的FileMode 為 append ? FileMode.Append : FileMode.Create
//文件如果被其他任務打開並處於Write模式,此處會拋出異常(該工具也含多處異常拋出,使用時務必考慮接收這些異常)
StreamWriter myCsvSw = new StreamWriter(new FileStream(yourFilePath, isAppend ? FileMode.Append :
FileMode.Create, FileAccess.Write, FileShare.ReadWrite), yourEncode);
if (yourDataSouse == null)
{
throw new Exception("your DataSouse is null");
}
WriteCsvVeiw(yourDataSouse, myCsvSw);
myCsvSw.Dispose();
}
public static void SaveCsvFile(string yourFilePath, List<List<string>> yourDataSouse)
{
SaveCsvFile(yourFilePath, yourDataSouse, false, defaultEncoding);
}
public static Stream OpenFile(string filePath)
{
Stream myStream;
try
{
myStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None);
}
catch (Exception)
{
return null;
}
return myStream;
}
#endregion
}
}
