close

在程式撰寫的過程中常常會使用到一些資訊的交換及傳輸,例如常見的XMLJSONCSV等等,其中在網路的資料傳輸又屬XMLJSON最常見,相對來說在一般本地端最常使用到的格式即是CSV,本篇文章將針對C#讀取CSV檔案進行解說。

一、CSV讀取:

第一節將從讀取開始,讀取檔案會透過FileStream,最終會將CSV檔案內容寫入到一個DataTable中,用於日後方便叫用,程式碼如下:

 

public static DataTable OpenCSV(string filePath) {
 FileStream fs = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read);
 StreamReader sr = new StreamReader(fs, Encoding.Default);
 //StreamReader sr = new StreamReader(fs, encoding);
 //string fileContent = sr.ReadToEnd();
 //記錄每次讀取的一行記錄
 DataTable dt = new DataTable();
 string strLine = "";
 //記錄每行記錄中的各字段內容
 string[] aryLine = null;
 string[] tableHead = null;
 //標示列數
 int columnCount = 2;
 //標示是否是讀取的第一行
 bool IsFirst = true;
 //逐行讀取CSV中的數據
 while ((strLine = sr.ReadLine()) != null) {
  if (IsFirst == true) {
   tableHead = strLine.Split(',');
   IsFirst = false;
   columnCount = tableHead.Length;
   //創建列
   for (int i = 0; i < columnCount; i++) {
    tableHead[i] = tableHead[i].Replace("\"", "");
    DataColumn dc = new DataColumn(tableHead[i]);
    dt.Columns.Add(dc);
   }
  } else {
   aryLine = strLine.Split(',');
   DataRow dr = dt.NewRow();
   for (int j = 0; j < columnCount; j++) {
    dr[j] = aryLine[j].Replace("\"", "");
   }
   dt.Rows.Add(dr);
  }
 }
 if (aryLine != null && aryLine.Length > 0) {
  dt.DefaultView.Sort = tableHead[2] + " " + "DESC";
 }
 sr.Close();
 fs.Close();
 return dt;
}

程式說明:

行2-3:用於讀取csv中所有資料,將資料存入StreamReader中。

行18-26isFirst用於判斷為第一次寫入資料,因為CSV表格的第一列通常用於存放表格名稱,故當判斷isFirsttrue時,會將讀到的設定為DataTable的表格名稱。

行28-33:第二列開始為資料內容,故開始寫入DataTable中。

Function最終會回傳一個DataTable

 

二、CSV寫入

此節會延續上節將DataTable轉成CSV資料格式並儲存至指定位置,程式碼如下:

public static bool SaveCSV(DataTable dt, string fullPath) {
 try {
  FileInfo fi = new FileInfo(fullPath);
  if (!fi.Directory.Exists) {
   fi.Directory.Create();
  }
  FileStream fs = new FileStream(fullPath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
  //StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.Default);
  StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
  string data = "";
  //寫出列名稱
  for (int i = 0; i < dt.Columns.Count; i++) {
   data += "\"" + dt.Columns[i].ColumnName.ToString() + "\"";
   if (i < dt.Columns.Count - 1) {
    data += ",";
   }
  }
  sw.WriteLine(data);
  //寫出各行數據
  for (int i = 0; i < dt.Rows.Count; i++) {
   data = "";
   for (int j = 0; j < dt.Columns.Count; j++) {
    string str = dt.Rows[i][j].ToString();
    str = string.Format("\"{0}\"", str);
    data += str;
    if (j < dt.Columns.Count - 1) {
     data += ",";
    }
   }
   sw.WriteLine(data);
  }
  sw.Close();
  fs.Close();
  return true;
 } catch {
  return false;
 }
}

程式說明:

Function的參數有DataTable及檔案儲存位置。

行3-5:檢查儲存路徑是否已有檔案存在,若沒有則新增。

12-16:將欄位名稱寫入Stream的第一列中。

20-29:將其餘資料寫入Stream中。

行30:將Stream寫入CSV檔中。

※注意在CSV檔案使用完畢後,要記得Close掉或Dispose掉,釋放被我們程式吃住的檔案,否則在下次開檔時程式會出現錯誤(Race Condition)


在工作時常常會遇到要跟別人的軟體整合的專案,在本地端做資料交換時很常會用到CSV檔案交換,將這部分的Function解說寫成文章,除了紀錄也方便自己日後查詢。

好了,以上是小弟個人關於CSVDataTable轉換的方法,給大家參考,如有誤人子弟之處,還請各位先進給予指教。

如果覺得本篇文章對你有幫助的話,也請別忘記按讚加留言給予鼓勵喔。

arrow
arrow
    創作者介紹
    創作者 zhong.jun.jimmy 的頭像
    zhong.jun.jimmy

    第一次寫程式就不上手

    zhong.jun.jimmy 發表在 痞客邦 留言(1) 人氣()