LoginSignup
13
12

More than 3 years have passed since last update.

*Android*内部ストレージへのファイルの保存・読み込み

Last updated at Posted at 2020-07-15

はじめに

こんにちは.今日から記事を書き始めます.
プログラミングのメモとしてQiitaを活用していくつもりです.
私は,Androidを使い始めて2年程になります.来年から就職する大学院生です.

今回は,Androidの内部ストレージへのファイルの保存・読み込みについて解説します.Androidのストレージに関する解説に関する記事は,どれも内容が少しずつ異なり,迷ってしまう方もいると思うので,標準的なものを書きます.

前提

開発環境は以下の通りです.
*Android Studio 4.0.1
*targetSdkVersion 28
*Google Nexus 5x

内部ストレージと外部ストレージ

Androidには,内部ストレージと外部ストレージが存在します.

■内部ストレージ

  • 常に利用できる
  • ファイルへのアクセスは,保存元のアプリからしかできない.
  • ユーザがアプリをアンインストールすると,ファイルは自動的に内部ストレージから削除される.

■外部ストレージ

  • マウントされていることを確認してから使用する必要がある.
  • ファイルへのアクセスに制限はない.

保存に使用するストレージは以下の3つがある.

  • 内部ストレージ
  • 外部ストレージのアプリ固有の領域
  • 外部ストレージの共有ファイルの領域

各ストレージは,Android StudioのDevice File Explorerの構造では以下に保存されます.

  • 内部ストレージ /data/data/パッケージ名/files/
  • 外部ストレージのアプリ固有の領域 /sdcard/Android/data/パッケージ名/files/
  • 外部ストレージの共有ファイルの領域 /sdcard/

ファイルを内部ストレージに保存する

ファイル保存では FileOutputStream のインスタンスを openFileOutput() メソッドを使用して取得します.これによりストリームを開くことができます.また,openFileOutput()を使用すると,内部ストレージのパスを指定しなくても,自動的にパスを取得して保存してくれます.

FileOutputStream fileOutputstream = openFileOutput("text.txt", Context.MODE_PRIVATE);

第1引数
"/パス/ファイル名"

第2引数

説明
MODE_WORLD_READABLE 他のアプリから参照可能
MODE_WORLD_WRITEABLE 他のアプリから書き込み可
MODE_PRIVATE 他のアプリからアクセス不可
MODE_APPEND ファイルがあると,追記

また、モードを複数指定する場合にはパイプを繋げると複数指定できます。
MODE_PRIVATE | MODE_APPEND

あとは,ファイルに書き出したい文字列をbyte型の配列に変換し, write() を使ってストリームに書き出します.

fileOutputStream.write(str.getBytes());

ファイルをストレージから読み込む

ファイルの読み込みでは FileInputStream のインスタンスを openFileInput() メソッドを使用して取得します.これにより,ストリームを開くことができます.

FileInputStream fileInputStream = openFileInput("text.txt");

InputStreamReader でストリームからバイトを読み込み、指定された文字にデコードします.それをBufferedReader に入れて、行毎に読み出します。変換効率を上げるため、BufferedReader の内部に InputStreamReader をラップするのがいいようです。

BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
String lineBuffer;
while (true){
    lineBuffer = reader.readLine();
    if (lineBuffer != null){
        text += lineBuffer;
    }
    else {
        break;
    }
}

サンプルコード

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="50dp"
        android:layout_marginTop="100dp"
        android:text="Save File"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="100dp"
        android:layout_marginTop="100dp"
        android:text="Read File"
        app:layout_constraintStart_toEndOf="@+id/button1"
        app:layout_constraintTop_toTopOf="parent" />
    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="120dp"
        android:text=""
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/editText" />
    <EditText
        android:id="@+id/editText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:ems="10"
        android:inputType="textPersonName"
        android:text="Name"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

MainActivity.java

package com.example.keita.myapplication;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class MainActivity extends AppCompatActivity {
    private TextView textView;
    private Button button1;
    private Button button2;
    private EditText editText;
    private String fileName = "test.txt";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.textView = findViewById(R.id.textView);
        this.editText = findViewById(R.id.editText);
        this.button1 = findViewById(R.id.button1);
        this.button2 = findViewById(R.id.button2);
        this.button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = editText.getText().toString();
                saveFile(fileName, text);
            }
        });
        this.button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String str = readFile(fileName);
                textView.setText(str);
            }
        });
    }


    private void saveFile(String file, String str){
        try {
            FileOutputStream fileOutputStream = openFileOutput(file, MODE_PRIVATE | MODE_APPEND);
            fileOutputStream.write(str.getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private String readFile(String file){
        String text = null;
        try {
            FileInputStream fileInputStream = openFileInput(file);
            BufferedReader reader = new BufferedReader(new InputStreamReader(fileInputStream, "UTF-8"));
            String lineBuffer;
            while (true){
                lineBuffer = reader.readLine();
                if (lineBuffer != null){
                    text += lineBuffer;
                }
                else {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return text;
    }
}
13
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
12