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