txt文字檔讀取

在企業中最常是用到的就是匯入訂單,有許多格式 例如:xls , xlsx 或是今天的主角 txt。

小菜鳥決定把用到的方法記錄在這,讓以後若又要用到不用再翻箱倒櫃天天請教google大神了。

txt檔案讀取

說到txt檔案讀取,網路上有各種做法。但不外乎就是一個一個讀取或是一行一行讀取,然後利用string.split去分割並存入陣列中。

第一次寫文字檔讀取,因為公司訂單太多文字檔內容格式都不相同,真的是搞死小菜鳥。


首先當我們要讀取txt檔之前,我們必須抓到這個檔案的絕對位置,一般在學校時教的都是直接抓取設計界面的FileUpload是否有檔案,再將檔名抓出並加到savePath裡

例如:

protected void Button2_Click(object sender, EventArgs e)
{
        String savePath = @"C:\arntc\upload";        

        if (FileUpload1.HasFile)
        {
            string filename = FileUpload1.FileName;
            savePath += filename;
            FileUpload1.SaveAs(savePath);
        }
}

但公司並不是寫在aspx.cs後端,而是將檔名或是路徑從前端透過JQuery Ajax 寫入AP server,此狀況又無法利用上方的方式去寫入檔案。

而是要在前端傳至後端檔案名稱,並在APserver 寫一個接收的方法將我們的fileName帶入這個filePath

public void getFilePath(fileName){
  //檔案路徑
   string filePath = @"C:\Program Files (x86)\" + fileName;
}

再來就是如何讀取檔案內容呢??

檔的讀取有兩種方式,一種是利用FileStream進行檔的讀取,並將它轉換成char陣列,然後輸出;一種是使用StreamReader讀取檔,然後一行一行的輸出。

網路上大部分皆指出FileStream 比起 StreamReader 速度來的慢,所以小菜鳥在這邊是利用StreamReader進行讀檔案

public void openTxt(string filePath){
   //透過路徑讀取檔案
   StreamReader sr = new StreamReader(filePath);
   string line;
   while ((line = sr.ReadLine()) != null){
      //開始一行一行讀取囉!!
      Console.WriteLine(line.ToString());
   }
}

這時如果你的文字檔裡面有中文字你就會看到一堆亂碼在那邊飛跳,

那是因為 .Net 的檔案處理預設為 Unicode ,但是文字檔大多還是以 ANSII 儲存,而且裡面的編碼還是用 Big5,所以才會造成中文亂碼的狀況。

解決辦法倒是滿簡單的,我們只要在讀取檔案時告知程式到底是哪個編碼,他就會乖乖的出現中文啦!

下面我們在讀取路徑的地方加上encode,便可以指定他為big5編碼

//使txt檔的中文字編碼改成big5 
System.Text.Encoding encode = System.Text.Encoding.GetEncoding("big5");
//透過路徑讀取檔案
StreamReader sr = new StreamReader(filePath, encode);

大致上讀取檔案及中文亂碼的問題都解決了,但碰到的困難永遠都不是只有這樣,小菜鳥看著我的訂單文字檔很煩悶,因為它呈現下方這種樣子。

它呈現並排的樣子且好多空格,讓菜鳥憂心忡忡不知怎辦,只好又去請教google大神


Google大神提供的方法,利用split 空格先去切割每一行讀取到的文字,並存入陣列。

這是個可行的辦法,但是我們的空格這麼多這樣我怎麼知道每個資料到底是在陣列的第幾個,因此必須再將陣列中所有的空格全部remove

但程式碼該怎麼寫呢?? 又困住了小菜鳥(已經被困住N遍了),又去拜訪Google大神

最終利用LinQ,透過 Enumerable.Where<TSource>方法 ,找出輸入資料符合條件的項目(MSDN)

string[] list; //要存入的陣列
//line為上方程式碼文字檔每行讀取的值,並利用split分割存入list中
list = line.ToString().Split(' '); 
string removeSpace = "";//欲將所有空格去除
list = list.Where(val => val != removeSpace).ToArray();

這樣就可以完整的去除所以的空格啦 !! 但你說結束了嗎??還沒小菜鳥又碰到另一種訂單了


這次的訂單大家有發現嗎??中間那個中文名稱兩行空格數不同,會導致我們利用空格切割時,會變成不同的切割數所以陣列所放入的欄位數會不一樣

那這樣我該如何抓去最後一排的數字呢?

最終的解決辦法是透過陣列長度從後面抓回來,例如 907772 這個陣列長度會是8 則我要抓到5 則會是
list [ list.Count -1 ] 


在還沒想到解決辦法前,主管跑來關心小菜鳥,他說他們都是利用絕對位置去抓各個欄位的數值,但若只要廠商訂單一更動位置,就會很慘~~

小菜鳥查了許久並沒有看到C# 有辦法讀取文字檔內容的絕對位置,若有的話再補起來


參考資料

文字檔讀寫 https://ppt.cc/fJKU6x

中文亂碼:https://dotblogs.com.tw/jean/2013/09/19/119076