【Kotlin/Android Studio】ファイルへ保存/取得する方法!FileWriter/openFileOutputの使い方

この記事からわかること
- Android Studio/Kotlinでデータをファイルへ保存する方法
- FileWriter/BufferedReaderの使い方
- openFileOutput/openFileInputの使い方
- useメソッドの使い方
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
ローカルへデータを保存する方法
アプリを停止後に再度起動した際にデータを消さずに保持したい場合はデバイス内(ローカル)やサーバー(クラウド)などにデータを保存する必要があります。Androidではローカルへ保存する方法がいくつかあります。
- ファイルで保存する
- DataStore/SharedPreferencesを使用する
- 外部ライブラリ(Roomなど)を使用する
【Kotlin/Android Studio】DataStoreの使い方!データの保存と取得方法
その中でもローカルへデータを永続的に保存しておく手段で一番シンプルな方法であるファイルを作成して保存する方法を紹介していきます。またファイルへ保存するのも異なる実装方法があります。
- FileWriter/BufferedReaderを使用する
- openFileOutput/openFileInputを使用する
FileWriterの使い方
Androidでファイルへ書き込みをするにはFileWriter
を使用します。引数に書き込みを行いたいFile
インスタンス(生成方法は後述)を渡します。use
メソッドを使用してFileWriterストリームを作成し、write
メソッドの引数として渡されたテキストを書き込みます。
おすすめ記事:Kotlin/Android】use関数の使い方!リソース(Closeable)の管理
try{
// ファイルへの書き込み
FileWriter(file).use{ stream -> stream.write(text) }
}catch (e: IOException){
Log.d("Error","保存失敗")
}
Fileインスタンスを生成する
実際にローカルに保存されるファイル情報を保持するFile
インスタンスをファイル名とパスを指定して生成します。applicationContext.filesDir
を使用することで/data/user/0/パッケージ名/files
へのパス情報を取得することが可能です。
// ファイル名
val filename = "sample.txt"
// 保存先のパス情報を指定してFileインスタンスを生成
file = File(applicationContext.filesDir, filename)
BufferedReaderの使い方
ファイルからデータを取得するためにはBufferedReader
を使用します。引数にFileReader(file)
インスタンスを渡しFileReader
の中に対象のFile
インスタンスを渡します。あとは先ほどと同様にストリームの中でreadLine
メソッドを使用することでファイルの中身を取得することができます。
var result: String = ""
try{
// ファイル内容の取得(1行のみ)
BufferedReader(FileReader(file)).use { stream -> result = stream.readLine() }
}catch(e: IOException){
Log.d("Error","取得失敗")
}
resultLabel.text = result
1行のみ取得したいならreadLine
、テキスト全体を取得したいならreadText
を使用します。
実装例
class MainActivity : AppCompatActivity() {
// ファイル情報を保持する変数
private lateinit var file: File
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val saveButton: Button = findViewById(R.id.save_button)
val readButton: Button = findViewById(R.id.read_button)
val resultLabel: TextView = findViewById(R.id.result_label)
// ファイル名
val filename = "sample.txt"
// 保存先のパス情報を指定してFileインスタンスを生成
file = File(applicationContext.filesDir, filename)
// 保存したい文字
val text = "Hello World!"
saveButton.setOnClickListener {
try{
// ファイルへの書き込み
FileWriter(file).use{ stream -> stream.write(text) }
}catch (e: IOException){
Log.d("Error","保存失敗")
}
}
readButton.setOnClickListener {
var result: String = ""
try{
// ファイル内容を全て取得
BufferedReader(FileReader(file)).use { stream -> result = stream.readText() }
}catch(e: IOException){
Log.d("Error","取得失敗")
}
resultLabel.text = result
}
}
}
openFileOutputの使い方
openFileOutput
を使用してもファイルへ書き込みをすることが可能です。openFileOutput
の引数には保存先のファイル名とモードを渡します。Context.MODE_PRIVATE
はファイルの保存先がプライベートな領域に保存されることを指定します。あとはuse
メソッドを使用してストリームを作成して書き込むだけです。書き込む際にOutputStreamWriter
を使用することでString型のまま渡すことが可能です。
try {
openFileOutput(filename, Context.MODE_PRIVATE).use { stream ->
OutputStreamWriter(stream, StandardCharsets.UTF_8).use { writer ->
writer.write(text)
}
}
} catch (e: IOException) {
Log.d("Error","保存失敗")
}
OutputStreamWriter
を使用しない場合はtoByteArray
でバイトデータに変換してから渡す必要があります。
openFileOutput( filename, Context.MODE_PRIVATE).use { stream -> stream.write(text.toByteArray())}
openFileInputの使い方
openFileInput
を使用しuse
メソッドを使用してストリームを作成してファイルの中身を取得していきます。 行ずつ取得したいなら以下のような感じ。
try {
openFileInput(filename).use { stream ->
BufferedReader(InputStreamReader(stream, StandardCharsets.UTF_8)).use { reader ->
var lineBuffer: String?
while (reader.readLine().also { lineBuffer = it } != null) {
result += lineBuffer + "\n"
}
}
}
} catch (e: IOException) {
Log.d("Error", "取得失敗")
}
一気に中身を取得したいなら以下で良いと思います。
openFileInput(filename).use { stream ->
BufferedReader(InputStreamReader(stream, StandardCharsets.UTF_8)).use { reader ->
result = reader.readText()
}
}
実装例
class MainActivity : AppCompatActivity() {
private val filename: String = "sample.txt"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val saveButton: Button = findViewById(R.id.save_button)
val readButton: Button = findViewById(R.id.read_button)
val resultLabel: TextView = findViewById(R.id.result_label)
// 保存したい文字
val text = "Hello World!"
saveButton.setOnClickListener {
try {
openFileOutput(filename, Context.MODE_PRIVATE).use { stream ->
OutputStreamWriter(stream, StandardCharsets.UTF_8).use { writer ->
writer.write(text)
}
}
} catch (e: IOException) {
Log.d("Error","保存失敗")
}
}
readButton.setOnClickListener {
var result: String = ""
try {
openFileInput(filename).use { stream ->
BufferedReader(InputStreamReader(stream, StandardCharsets.UTF_8)).use { reader ->
var lineBuffer: String?
while (reader.readLine().also { lineBuffer = it } != null) {
result += lineBuffer + "\n"
}
}
}
} catch (e: IOException) {
Log.d("Error", "取得失敗")
}
// 改行を削除してresultLabelに表示
resultLabel.text = result.trim()
}
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。