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

この記事からわかること

  • Android Studio/Kotlinデータファイルへ.保存する方法
  • FileWriter/BufferedReader使い方
  • openFileOutput/openFileInputの使い方
  • useメソッドの使い方

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

ローカルへデータを保存する方法

アプリを停止後に再度起動した際にデータを消さずに保持したい場合はデバイス内(ローカル)やサーバー(クラウド)などにデータを保存する必要があります。Androidではローカルへ保存する方法がいくつかあります。

  1. ファイルで保存する
  2. DataStore/SharedPreferencesを使用する
  3. 外部ライブラリ(Roomなど)を使用する

その中でもローカルへデータを永続的に保存しておく手段で一番シンプルな方法であるファイルを作成して保存する方法を紹介していきます。またファイルへ保存するのも異なる実装方法があります。

FileWriterの使い方

Androidでファイルへ書き込みをするにはFileWriterを使用します。引数に書き込みを行いたいFileインスタンス(生成方法は後述)を渡します。useメソッドを使用してFileWriterストリームを作成し、writeメソッドの引数として渡されたテキストを書き込みます。

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()
        }
    }
}

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index