安安泥好,這是雷哥的Android開發筆記。
有些時候,我們會想要在app裡面放入預設資料。不過全部都寫成code感覺很難維護又不符合規範。
這時候,如果能夠將資料寫成csv並放在專案裡,就可以大幅提升專案的可讀和可維護性了。
這就是本篇筆記的主題:如何讀取預放置在專案裡的csv檔案呢?
主要使用庫: openCSV
涉及技術與觀念: csv, assets, reader
觀念
如果這篇Stack Overflow回答講的沒錯的話,只要匯入openCSV就可以透過 CSVReader
來讀取檔案了。(讀出的資料格式為String陣列)
你只要照著以下步驟做即可:
- 準備好一份csv檔案,並將其放入assets資料夾
- 在app的gradle裡面匯入
openCSV
函式庫 - 呼叫
CSVReader
來為你取得資料。結束!
聽起來很簡單對吧?以下將一一教學。
檔案存放:如何創建assets資料夾
在Android裡面存放專案非程式碼的檔案,通常有兩種選擇。一種選擇是放置在 res/raw
資料夾下方;另一種則是創建 assets
資料夾。他們都可以保存檔案、使其不被Android亂轉換。他們的最大差別有2個:一個是前者會被Android自動編成編號,使你可以透過 R.raw.file
的方式在code中進行呼叫,而 assets
資料夾則需要透過 AssetManager
或其他庫存取。另一個是 res/raw
底下不能再有目錄(資料夾),但是 assets
下方可以。
為了確保專案以後檔案好整理,我建議使用 assets
資料夾。
在專案中創建 assets
資料夾的方法,網路上有很多教學了。這裡就簡介兩種作法:
- 簡單粗暴型:直接開啟檔案總管,跑去你專案的
app\src\main
資料夾下方置入assets資料夾(也就是app\src\main\assets
)。理論上這就可以直接用了。 - 使用Android Studio內建功能:其實Android Studio有為我們提供創建方法,只要對著
app
資料夾點右鍵->New
->Folder
->Assets Folder
,並且按照提示視窗步驟就可以創建完成了。這篇有一篇圖文並茂的Stack Overflow解答可供參考。
完成後,記得將你的csv檔案放進資料夾裡面喔。
在App的Gradle中匯入open CSV庫
沒什麼好說的,就加入一行:
implementation 'com.opencsv:opencsv:4.6'
這可能不是最新版本。如果不是的話,Android Studio會跳警告,照著建議替換就好。
完成後記得sync gradle。
呼叫CSV Reader來為你取得資料
二話不說,供上範例程式碼:
try {
CSVReader reader = new CSVReader(new FileReader("myfile.csv"));
String[] nextLine;
int i = 0;
// reader.readNext()會讀取你csv一列的內容並轉換成字串陣列,例如
// column1, column2, "column
// 3"
// 就會被拆成3個字串。這邊就看你想怎麼使用
while ((nextLine = reader.readNext()) != null) {
System.out.println("Reader read file content- Line " + i + ": " + nextLine[0] + "," + nextLine[1] + "etc...");
i++;
}
} catch (IOException e) {
// reader在初始化時可能遭遇問題。記得使用try/catch處理例外情形。
e.printStackTrace();
}
如果你的專案有神力庇護,那麼到這裡可能就完成了。
如果沒有的話…你可能會收到跟我一樣的Exception訊息:
java.io.FileNotFoundException: myfile.csv (No such file or directory)
你一定會想罵聲甘霖老師。為什麼都照著做了,還是沒有成功呢?大大你倒是告訴我為什麼啊QQ
先別急著哭,因為我已經遇過這個問題了。後來我發現似乎是 FileReader
用在 CSVReader
的初始化會出問題,照著這篇解答改使用 InputStreamReader
就可以成功囉:
CSVReader reader = new CSVReader(new InputStreamReader(
(context).getAssets().open("myfile.csv")
));
補充:如果你是在AndroidTest的環境的話,可以使用下列方法取得正確的context:
Context appContext = InstrumentationRegistry.getTargetContext();
後記
其實, openCSV
庫還有提供很多功能,例如寫入。
只要掌握好基本觀念,相信要進一步延伸使用到讀取其他地方的CSV、或者寫入檔案,應該都不是問題。
我是雷哥,一位萌新開發者。歡迎與我交流、討論遊戲與Android App開發技巧。如果我的文章有幫助到您,也請不吝給點掌聲 :)