Androidのファイル入出力処理
サンプルコードの紹介の前に、少しAndroidでのファイル入出力処理全般の話をしておきます。Androidでも、ファイル入出力処理は、これまで説明した手順と大差はありません。ただ注意すべき点(主にハードウェアに依存する部分)もあります。
入出力ファイルの位置
Androidでは、任意の場所にあるファイルを、自由に操作することは許されていません。端末の内部にあるストレージなら、アプリケーションから入出力できるのは、/data/data/[パッケージ名]/files/以下のファイルと決められています。そのため、パス名を指定してストリームオブジェクトを生成する場合、このパスを指定しないとエラーになってしまいます。
専用メソッド
Androidでは、ファイルのストリームを取得するための専用メソッドとして、openFileInput、openFileOutputというふたつのメソッドがContextクラスに用意されています。これらのメソッドでは、規定のパス名の指定が不要になります(指定できない)。また戻り値として、FileInputStream/FileOutputStreamオブジェクトを返します。
ファイル出力
次のサンプルは、openFileOutputメソッドを使って、ファイルにテキストを書きだす例です。
try {
OutputStreamWriter osw = new OutputStreamWriter(
openFileOutput("sample.txt" Context.MODE_WORLD_READABLE));
BufferedWriter bw = new BufferedWriter(osw);
try {
bw.write("abc");
bw.newLine(); // 改行の出力
}
finally {
bw.close();
}
}
catch (IOException e) {
}
なお、openFileOutputメソッドの第2引数はファイルの操作モードです。次の定数が指定でき、or(|)で区切ることで複数指定も可能です。
| 定数 | 概要 |
| MODE_APPEND | 追記モードで開く |
| MODE_PRIVATE | 作成したアプリケーションのみアクセス可能にする |
| MODE_WORLD_READABLE | 他アプリケーションの読み込み可にする |
| MODE_WORLD_WRITEABLE | 他アプリケーションの書き込み可にする |
Androidエミュレータでファイルが作成されていることを確かめるには、インストールされているTerminalEmulatorアプリ([Dev Tools]にある)を起動します。次のように、ファイルが作成されていることが確認できます。
PrintWriterクラス
テキストの出力には、もっと使い勝手のよいストリームクラスも用意されています。PrintWriterクラスを使うと、書式付きでテキストを出力できます。次のようにC言語のようなprintfメソッドも利用できます。
PrintWriter pw = new PrintWriter( new BufferedWriter(osw) );
try {
int n1 = 123;
float n2 = 12.3f;
pw.printf("%d %3.2f\n", n1, n2); // 出力文字列:123 12.30
}
finally {
pw.close();
}
ファイル入出力のサンプル
最後に、ファイルの書き込みと読み込み、そして読み取った内容を画面に表示するサンプルを紹介します。
まず、main.xmlです。今回は次のように、ベースのレイアウトにIDを付与しておきます。レイアウトを参照する際に、このIDが必要なためです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/parent"
>
</LinearLayout>
サンプルソースは、次のようになります。画面表示は、ベースとなるレイアウトに、TextViewコンポーネントを追加する形をとっています。
public class HelloAndroid extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// ベースのレイアウト取得
LinearLayout parent = (LinearLayout) findViewById(R.id.parent);
String f = "sample.txt";
createTable(f); // ファイル作成
try {
BufferedReader br = new BufferedReader(new InputStreamReader(
openFileInput(f)));
try {
String line;
while ((line = br.readLine()) != null) {
TextView tv = new TextView(this);
tv.setTypeface(Typeface.MONOSPACE); // 等幅フォントの指定
tv.setText(line);
parent.addView(tv); // ビューの追加
}
} finally {
br.close();
}
} catch (IOException e) {
}
}
// ファイルに九九表を出力する
public void createTable(String f) {
try {
PrintWriter pw = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(openFileOutput(f,
Context.MODE_WORLD_READABLE))));
try {
for (int i = 1; i < 10; i++) {
for (int j = 1; j < 10; j++) {
pw.printf("%3d ", i * j);
}
pw.printf("\n");
}
} finally {
pw.close();
}
} catch (IOException e) {
}
}
}
まずcreateTableメソッドで、ファイルに九九表を出力しています。さきほどのPrintWriterクラスを用いて、数値を書き込んでいます。
ファイルの読み込みは、openFileInputメソッドで入力ストリームを取得し、InputStreamReaderとBufferedReaderクラスを使って、1行ずつ処理しています。取得した1行は、それぞれテキストビューに設定して(setTextメソッド)、レイアウトに追加(addViewメソッド)しています。なお、ここでは、フォントを等幅にするために、setTypefaceメソッドで、フォントファミリーにTypeface.MONOSPACEの指定をしています。ちなみにこれ以外では、Typeface.SERIF、Typeface.SANS_SERIFが指定できます。
実行結果は次のようになります。もちろんファイルにも、まったく同様の内容が出力されています。
最後に
今回は、ストリームを用いたファイル入出力の基本的な処理を説明しました。次回は、基本APIの中で、日付の処理など、まだ説明していなかったAPIをとりあげることにします。
参考資料
- 『Javaポケットリファレンス』 WINGSプロジェクト 高江賢 著、山田祥寛 監修、技術評論社、2011年3月
- Java Platform, Standard Edition 6 API 仕様
- Android Developers


