Androidのファイル入出力で結構悩んだのでそのメモ。
Androidでは、誰でも好きなパスに書き込みができるわけではありません!アプリの権限の許された部分のみに書き込みできます。書き込みができるのは、次のディレクトリです。
可能なパス | 補足 |
---|---|
/sdcard/xxx | SDカード |
/data/data/パッケージ名/xxx | データフォルダ |
ニアミスとして、test というファイルを書こうと頑張っていて、なぜか書けない・・・なぜだ~と悩んでいたら、test というフォルダが既にあったんです。間違っていたのは、以下のようなコード。
File f = new File("/sdcard/hoge/test.txt"); f.mkdirs(); // ←ここが間違い // フォルダなので当然エラー!! FileOutputStream fo = new FileOutputStream(f);
この時に、f.canWrite() で調べても、true が返ってくるので、なぜだ?!と思っていたのですが、ぼーっとしていて、フォルダとファイルの区別がついていなかったというオチ。
Androidのリソースとしてファイルを埋め込んだ場合、つまり、assets ディレクトリの場合。単純に /android_assets/xxx のようなパスを書いてもファイルを取り出せません。AssetManager を使ってファイルをオープンする必要があります。以下、アセットからSDカードにファイルをコピーするメソッド。
private static int BUFFSIZE = 1024 * 16; public static boolean copyAssetsFile(Activity app, String assetsName, String savepath) { FileOutputStream fo; InputStream inp; try { File f = new File(savepath); File parent = f.getParentFile(); if (parent != null && parent.canWrite()) { parent.mkdirs(); } fo = new FileOutputStream(f); } catch (IOException e) { Log.e("myapp", "copyAssetsFile() savepath could not open:" + e.getMessage() + ",file=" + savepath); return false; } AssetManager am = app.getResources().getAssets(); try { byte[] buf = new byte[BUFFSIZE]; inp = am.open(assetsName); while (true) { int sz = inp.read(buf, 0, BUFFSIZE); if (sz <= 0) break; fo.write(buf, 0, sz); } fo.close(); return true; }catch(IOException e) { Log.e("myapp", e.getMessage()); return false; } }
後は、単純にパスを書き間違えていたとか、そんな感じです。