Android Kotlin語言下的文件存儲

目錄

將數據存儲到文件中

創建文件和保存數據

讀取文件

SharedPreferences存儲

存儲數據到SharedPreferences中

Context類中的getSharedPreferences()方法

Activity類中的getPreferences()方法

從SharedPreferences中讀取數據

SQLite數據庫存儲

創建數據庫

調用數據庫

操作數據庫

升級數據庫


將數據存儲到文件中

創建文件和保存數據

Context類中提供了一個openFileOutput()方法,可以用于將數據存儲到指定的文件中。這個方法接收兩個參數:第一個參數是文件名,在文件創建的時候使用,注意這里指定的文件名不可以包含路徑,因為所有的文件都默認存儲到/data/data/<package name>/files/目錄下;第二個參數是文件的操作模式,主要有MODE_PRIVATEMODE_APPEND兩種模式可選,默認是MODE_PRIVATE,表示當指定相同文件名的時候,所寫入的內容將會覆蓋原文件中的內容,而MODE_APPEND則表示如果該文件已存在,就往文件里面追加內容,不存在就創建新文件。其實文件的操作模式本來還有另外兩種:MODE_WORLD_READABLEMODE_WORLD_WRITEABLE。這兩種模式表示允許其他應用程序對我們程序中的文件進行讀寫操作,不過由于這兩種模式過于危險,很容易引起應用的安全漏洞,已在Android 4.2版本中被廢棄。

openFileOutput()方法返回的是一個FileOutputStream對象,得到這個對象之后就可以使用Java流的方式將數據寫入文件中了。以下是一段簡單的代碼示例,展示了如何將一段文本內容保存到文件中:

    fun saveFile(saveString: String) {val output = openFileOutput("fileName", Context.MODE_PRIVATE)val writer = BufferedWriter(OutputStreamWriter(output))writer.use {it.write(saveString)}}

這里通過openFileOutput()方法能夠得到一個FileOutputStream對象,然后借助它構建出一個OutputStreamWriter對象,接著再使用OutputStreamWriter構建出一個BufferedWriter對象,這樣你就可以通過BufferedWriter將文本內容寫入文件中了。

注意,這里還使用了一個use函數,這是Kotlin提供的一個內置擴展函數。它會保證在Lambda表達式中的代碼全部執行完之后自動將外層的流關閉,這樣就不需要我們再編寫一個finally語句,手動去關閉流了,是一個非常好用的擴展函數。

另外,Kotlin是沒有異常檢查機制(checked exception)的。這意味著使用Kotlin編寫的所有代碼都不會強制要求你進行異常捕獲或異常拋出。即使你不寫try catch代碼塊,在Kotlin中依然可以編譯通過。

讀取文件

類似于將數據存儲到文件中,Context類中還提供了一個openFileInput()方法,用于從文件中讀取數據。這個方法要比openFileOutput()簡單一些,它只接收一個參數,即要讀取的文件名,然后系統會自動到/data/data/<package name>/files/目錄下加載這個文件,并返回一個FileInputStream對象,得到這個對象之后,再通過流的方式就可以將數據讀取出來了。

以下是一段簡單的代碼示例,展示了如何從文件中讀取文本數據:

    fun loadFile(): String {val stringBuilder = StringBuilder()val input = openFileInput("fileName")val reader = BufferedReader(InputStreamReader(input))reader.use {reader.forEachLine {stringBuilder.append(it)}}return stringBuilder.toString()}

在這段代碼中,首先通過openFileInput()方法獲取了一個FileInputStream對象,然后借助它又構建出了一個InputStreamReader對象,接著再使用InputStreamReader構建出一個BufferedReader對象,這樣我們就可以通過BufferedReader將文件中的數據一行行讀取出來,并拼接到StringBuilder對象當中,最后將讀取的內容返回就可以了。

注意,這里從文件中讀取數據使用了一個forEachLine函數,這也是Kotlin提供的一個內置擴展函數,它會將讀到的每行內容都回調到Lambda表達式中,我們在Lambda表達式中完成拼接邏輯即可。

SharedPreferences存儲

存儲數據到SharedPreferences中

要想使用SharedPreferences存儲數據,首先需要獲取SharedPreferences對象。Android中主要提供了以下兩種方法用于得到SharedPreferences對象。

  1. Context類中的getSharedPreferences()方法

    此方法接收兩個參數:第一個參數用于指定SharedPreferences文件的名稱,如果指定的文件不存在則會創建一個,SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs/目錄下的;第二個參數用于指定操作模式,目前只有默認的MODE_PRIVATE這一種模式可選,它和直接傳入0的效果是相同的,表示只有當前的應用程序才可以對這個SharedPreferences文件進行讀寫。其他幾種操作模式均已被廢棄,MODE_WORLD_READABLEMODE_WORLD_WRITEABLE這兩種模式是在Android 4.2版本中被廢棄的,MODE_MULTI_PROCESS模式是在Android 6.0版本中被廢棄的。

  2. Activity類中的getPreferences()方法

    這個方法和Context中的getSharedPreferences()方法很相似,不過它只接收一個操作模式參數,因為使用這個方法時會自動將當前Activity的類名作為SharedPreferences的文件名。

    得到了SharedPreferences對象之后,就可以開始向SharedPreferences文件中存儲數據了,主要可以分為3步實現。

    (1) 調用SharedPreferences對象的edit()方法獲取一個SharedPreferences.Editor對象。

    (2) 向SharedPreferences.Editor對象中添加數據,比如添加一個布爾型數據就使用putBoolean()方法,添加一個字符串則使用putString()方法,以此類推。

    (3) 調用apply()方法將添加的數據提交,從而完成數據存儲操作。

?代碼示例如下

    fun saveSharedPreferences(saveString: String){val edit = getSharedPreferences("fileName",Context.MODE_PRIVATE).edit()edit.putString("editName","editValue")edit.apply()}

從SharedPreferences中讀取數據

SharedPreferences對象中提供了一系列的get方法,用于讀取存儲的數據,每種get方法都對應了SharedPreferences.Editor中的一種put方法,比如讀取一個布爾型數據就使用getBoolean()方法,讀取一個字符串就使用getString()方法。這些get方法都接收兩個參數:第一個參數是鍵,傳入存儲數據時使用的鍵就可以得到相應的值了;第二個參數是默認值,即表示當傳入的鍵找不到對應的值時會以什么樣的默認值進行返回。

代碼示例如下

    fun loadSharedPreferences(): String {val sharedPreferences = getSharedPreferences("fileName", Context.MODE_PRIVATE)return sharedPreferences.getString("editName", "defValue")!!}

SQLite數據庫存儲

創建數據庫

Android為了讓我們能夠更加方便地管理數據庫,專門提供了一個SQLiteOpenHelper幫助類,借助這個類可以非常簡單地對數據庫進行創建和升級。既然有好東西可以直接使用,那我們自然要嘗試一下了,下面我就對SQLiteOpenHelper的基本用法進行介紹。

首先,你要知道SQLiteOpenHelper是一個抽象類,這意味著如果我們想要使用它,就需要創建一個自己的幫助類去繼承它。SQLiteOpenHelper中有兩個抽象方法:onCreate()onUpgrade()。我們必須在自己的幫助類里重寫這兩個方法,然后分別在這兩個方法中實現創建和升級數據庫的邏輯。

SQLiteOpenHelper中還有兩個非常重要的實例方法:getReadableDatabase()getWritableDatabase()。這兩個方法都可以創建或打開一個現有的數據庫(如果數據庫已存在則直接打開,否則要創建一個新的數據庫),并返回一個可對數據庫進行讀寫操作的對象。不同的是,當數據庫不可寫入的時候(如磁盤空間已滿),getReadableDatabase()方法返回的對象將以只讀的方式打開數據庫,而getWritableDatabase()方法則將出現異常。

SQLiteOpenHelper中有兩個構造方法可供重寫,一般使用參數少一點的那個構造方法即可。這個構造方法中接收4個參數:第一個參數是Context,這個沒什么好說的,必須有它才能對數據庫進行操作;第二個參數是數據庫名,創建數據庫時使用的就是這里指定的名稱;第三個參數允許我們在查詢數據的時候返回一個自定義的Cursor,一般傳入null即可;第四個參數表示當前數據庫的版本號,可用于對數據庫進行升級操作。構建出SQLiteOpenHelper的實例之后,再調用它的getReadableDatabase()getWritableDatabase()方法就能夠創建數據庫了,數據庫文件會存放在/data/data/<package name>/databases/目錄下。此時,重寫的onCreate()方法也會得到執行,所以通常會在這里處理一些創建表的邏輯。

我們建立一個代碼示例如下:

class MyDatabaseHelper(private val context: Context,private val databaseName: String,val version: Int
) : SQLiteOpenHelper(context, databaseName, null, version) {private val createTable = "create table tableName(id integer primary key autoincrement, " +"key1 text," +"key2 real," +"key3 integer)"override fun onCreate(db: SQLiteDatabase?) {db?.execSQL(createTable)}override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {}
}

調用數據庫

val myDatabaseHelper =MyDatabaseHelper(this,"databaseName",1)
myDatabaseHelper.writableDatabase

操作數據庫

val myDatabaseHelper = MyDatabaseHelper(this, "databaseName", 1)
val db = myDatabaseHelper.writableDatabase
val value1 = ContentValues().apply {put("key1", "111")put("key2", 1.1)put("key3", 1)
}
db.insert("tableName", null, value1)val value2 = ContentValues().apply {put("key1", "222")put("key2", 2.2)put("key3", 2)
}
db.insert("tableName", null, value2)
db.delete(tableName, "key2 = ? and key3 = ? ", arrayOf("2.2","2"))
val value3 = ContentValues().apply {put("key1", "444")}
db.update(tableName, value3, "key2 = ?", arrayOf("1.1"))
        val course = db.query(tableName, null, null, null, null, null, null)if (course.moveToFirst()) {do {println(course.getString(course3.getColumnIndex("key1")))println(course.getString(course.getColumnIndex("key2")))println(course.getString(course.getColumnIndex("key3")))} while (course.moveToNext())}course.close()

升級數據庫

在MyDatabaseHelper類中,我們還有一個onUpgrade的方法沒有使用,這個方法就是用來升級數據庫的,當我們需要升級數據庫時,改寫MyDatabaseHelper的version,讓它大于我們直接傳入的數,這樣就會自動調用onUpgrade,示例代碼如下:

val myDatabaseHelper = MyDatabaseHelper(this, databaseName, 2)

然后我們在onUpgrade方法中編寫升級邏輯,代碼如下:

class MyDatabaseHelper(private val context: Context,private val databaseName: String,val version: Int
) : SQLiteOpenHelper(context, databaseName, null, version) {private val createTable = "create table tableName(id integer primary key autoincrement, " +"key1 text," +"key2 real," +"key3 integer)"private val createTable2 = "create table tableName2(id integer primary key autoincrement, " +"key1 text," +"key2 real," +"key3 integer)"override fun onCreate(db: SQLiteDatabase?) {db?.execSQL(createTable)db?.execSQL(createTable2)}override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {if (oldVersion<=1){db?.execSQL(createTable2)}}
}

當原來的版本是1時,我們就創建表2,不然就執行onCreate方法,創建表1表2。如果后續我們需要再表1中增加一個字段? tableName_id,那么我們將傳入的version改成3,再在onUpgrade方法中編寫如下代碼:

    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {if (oldVersion<=1){db?.execSQL(createTable2)}if (oldVersion<=2){db?.execSQL("alter table tableName add column tableName_id integer")}}

這樣我們就能在表1中新增一個tableName_id字段了

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209321.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209321.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209321.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java導出word

原文地址 傳入的值不能為null,否則會報錯&#xff0c;IXDocReport 有自己的判null規則&#xff0c;比較麻煩&#xff0c;建議代碼直接把null替換成"" public void exportWord1(WeeklyMeetDataDto dto, HttpServletResponse response) {ServletOutputStream downLoad…

Ignis - Interactive Fire System

Ignis - 點火、蔓延、熄滅、定制! 全方位火焰系統。 這個插件在21年的項目中使用過很好用值使用概述 想玩火嗎?如果想的話,那么Ignis就是你的最佳工具。有了Ignis,你可以把任何物體、植被或帶皮帶骨的網狀物轉換為可燃物體,它就會自動著火。然后,火焰可以蔓延,點燃其他物…

Java 一對多

前言 Internet 協議集支持一個無連接的傳輸協議&#xff0c;該協議稱為用戶數據報協議&#xff08;UDP&#xff0c;User Datagram Protocol&#xff09;。UDP 為應用程序提供了一種無需建立連接就可以發送封裝的 IP 數據包的方法。 此代碼就是基于UDP協議編寫。 通常把一對多的…

【docker 】centOS 安裝docker

官網 docker官網 github源碼 卸載舊版本 sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine 安裝軟件包 yum install -y yum-utils \device-mapper-persistent-data…

【優選算法系列】【專題二滑動窗口】第四節.30. 串聯所有單詞的子串和76. 最小覆蓋子串

文章目錄 前言一、串聯所有單詞的子串 1.1 題目描述 1.2 題目解析 1.2.1 算法原理 1.2.2 代碼編寫 1.2.3 題目總結二、最小覆蓋子串 2.1 題目描述 2.2 題目解析 2.2.1 算法原理 2.2.2 代碼編寫 …

【Docker】進階之路:(四)操作容器

【Docker】進階之路&#xff1a;&#xff08;四&#xff09;Docker容器 容器的生命周期創建容器docker createdocker run 管理容器查看運行的容器&#xff1a;查看所有容器&#xff1a; 啟動與終止啟動容器終止容器 進入容器docker attachdocker exec 導出和導入導出導入 容器的…

淺談5G基站節能及數字化管理解決方案的設計與應用-安科瑞 蔣靜

截至2023年10月&#xff0c;我國5G基站總數達321.5萬個&#xff0c;占全國通信基站總數的28.1%。然而&#xff0c;隨著5G基站數量的快速增長&#xff0c;基站的能耗問題也逐漸日益凸顯&#xff0c;基站的用電給運營商帶來了巨大的電費開支壓力&#xff0c;降低5G基站的能耗成為…

actitivi自定義屬性(二)

聲明&#xff1a;此處activiti版本為6.0 此文章介紹后端自定義屬性解析&#xff0c;前端添加自定義屬性方法連接&#xff1a;activiti自定義屬性&#xff08;一&#xff09;_ruoyi activiti自定義標題-CSDN博客 1、涉及到的類如下&#xff1a; 簡介&#xff1a;DefaultXmlPar…

在 JavaScript 中導入和導出 Excel XLSX 文件:SpreadJS

在 JavaScript 中導入和導出 Excel XLSX 文件 2023 年 12 月 5 日 使用 MESCIUS 的 SpreadJS 將完整的 JavaScript 電子表格添加到您的企業應用程序中。 SpreadJS 是一個完整的企業 JavaScript 電子表格解決方案&#xff0c;用于創建財務報告和儀表板、預算和預測模型、科學、工…

【華為OD】給定一個只包括 ‘(‘,‘)‘,‘{‘,‘}‘,‘[‘,‘]‘ 的字符串

給定一個只包括 (,),{,},[,] 的字符串 s , 判斷字符串是否有效。 有效字符串需滿足: 左括號必須用相同類型的右括號閉合。 左括號必須以正確的順序閉合。 示例 1 : 輸入:s="()" 輸出 : true 示例 2 :

圖的搜索(一):廣度優先搜索算法和深度優先搜索算法

圖的搜索&#xff08;一&#xff09;&#xff1a;廣度優先搜索算法和深度優先搜索算法 本章主要記錄了圖的搜索算法&#xff0c;和可以解決圖的基本問題——最短路徑問題的算法。本章主要對圖搜索的相關算法進行了介紹&#xff1a;廣度優先搜索算法、深度優先搜索算法。 下一…

公網域名如何解析到內網IP服務器——快解析域名映射外網訪問

在本地搭建主機應用后&#xff0c;由于沒有公網IP或沒有公網路由權限&#xff0c;在需要發布互聯網時&#xff0c;就需要用到外網訪問內網的一些方案。由于內網IP在外網不能直接訪問&#xff0c;通常就用通過外網域名來訪問內網的方法。那么&#xff0c;公網域名如何解析到內網…

Tmux中使用Docker報錯 - 解決方案

問題 進入Tmux會話后&#xff0c;在其中使用Docker可能會出現如下報錯&#xff1a; Got permission denied while trying to connect to the Docker ……解決方案 退出tmux會話: tmux detach在tmux會話外部殺掉tmux進程&#xff1a; pkill -f tmux重新進入tmux&#xff1a…

權威認證!景聯文科技入選杭州市2023年第二批省級“專精特新”中小企業認定名單

為深入貫徹黨中央國務院和省委省政府培育專精特新的決策部署&#xff0c;10月7日&#xff0c;杭州市經濟和信息化委員會公示了2023年杭州“專精特新”企業名單&#xff08;第二批&#xff09;。 根據工業和信息化部《優質中小企業梯度培育管理暫行辦法》&#xff08;工信部企業…

【Vue3+Ts項目】硅谷甄選 — 路由配置+登錄模塊+layout組件+路由鑒權

一、路由配置 項目一共需要4個一級路由&#xff1a;登錄&#xff08;login&#xff09;、主頁&#xff08;home&#xff09;、404、任意路由&#xff08;重定向到404&#xff09;。 1.1 安裝路由插件 pnpm install vue-router 1.2 創建路由組件 在src目錄下新建views文件…

Graphpad Prism10.1.0 安裝教程 (含Win/Mac版)

GraphPad Prism GraphPad Prism是一款非常專業強大的科研醫學生物數據處理繪圖軟件&#xff0c;它可以將科學圖形、綜合曲線擬合&#xff08;非線性回歸&#xff09;、可理解的統計數據、數據組織結合在一起&#xff0c;除了最基本的數據統計分析外&#xff0c;還能自動生成統…

Python:核心知識點整理大全8-筆記

目錄 ?編輯 4.5 元組 4.5.1 定義元組 dimensions.py 4.5.2 遍歷元組中的所有值 4.5.3 修改元組變量 4.6 設置代碼格式 4.6.1 格式設置指南 4.6.2 縮進 4.6.3 行長 4.6.4 空行 4.6.5 其他格式設置指南 4.7 小結 第5章 if語句 5.1 一個簡單示例 cars.py 5.2 條…

現代皮質沙發模型材質編輯

在線工具推薦&#xff1a; 3D數字孿生場景編輯器 - GLTF/GLB材質紋理編輯器 - 3D模型在線轉換 - Three.js AI自動紋理開發包 - YOLO 虛幻合成數據生成器 - 三維模型預覽圖生成器 - 3D模型語義搜索引擎 當談到游戲角色的3D模型風格時&#xff0c;有幾種不同的風格&#xf…

線性容器(QByteArray、QString、QList模板類)、堆棧窗體

QT 線性容器 點擊查看&#xff1a;字符和字節的區別&#xff0c;ASCII、Unicode 和 UTF-8 編碼的區別。&#xff08;&#x1f448; 安全鏈接&#xff0c;放心跳轉&#xff09; QByteArray 思考&#xff1a;char buf[6] “hello”; 如果 C 語言中要利用 buf 內容重新生成 “…

學生備考使用臺燈到底好不好?公認好用的護眼臺燈推薦

在現代生活中&#xff0c;許多學生的學習壓力越來越大&#xff0c;面臨的近視幾率也越來越大&#xff0c;特別是初中生&#xff0c;眼睛發育還未完全&#xff0c;使用不恰當的燈光也會對眼睛造成損害&#xff0c;特別是護眼臺燈。雖然護眼臺燈在功能上能夠提供充足、柔和的光線…