assetsに置いたデータベースファイルをdatabesesフォルダにコピーする方法

1,228 views
Skip to first unread message

ロウキル

unread,
Oct 3, 2010, 10:32:42 AM10/3/10
to 日本Androidの会
初めて投稿させていただきます。ロウキルといいます。

android開発を始めたばかり(javaも初めて勉強しています・・・)の初心者のため
検討違いの質問でしたら申し訳ありません。

データベースファイルを初回起動時に、databesesフォルダに移動したいと考えています。
以下のようなソースを書いたのですが。。。OutputStreamの所①でエラーになってしまいます。
ルート権限のあるフォルダ?なのでアクセスが失敗してるのかと思いますが、ほかに方法が見つけられませんでした。
何か良い方法はありますでしょうか。。。また別の方法でも構いませんので、教えて頂きたいです。

どうかよろしくお願いいたします。

private final void copy() throws IOException {
final String fileDb =
this.getDatabasePath("test.db").getPath(); //this.getAssets().

InputStream fileInputStream =
this.getAssets().open("test.db");
OutputStream output = openFileOutput(fileDb,
Context.MODE_WORLD_WRITEABLE);//・・・①

int DEFAULT_BUFFER_SIZE = 1024 * 4;
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int n = 0;

while (-1 != (n = fileInputStream.read(buffer))) {
output.write(buffer, 0, n);
}
fileInputStream.close();
output.close();
}

magpad

unread,
Oct 4, 2010, 1:09:31 AM10/4/10
to 日本Androidの会
こんにちは

openFileOutput()のとこってIllegalArgumentExceptionで落ちてたりしますか?

openFileOutput (String name, int mode)のnameにはパス(「/」等)を入れられないので、
FileOutputStreamとかで作成してみるといいと思います。

FileOutputStream output = new
FileOutputStream(getDatabasePath("test.db").getPath(), false);
みたいな。
(但し、SQLiteDatabase#getReadableDatabase()等でDBが作成されてるのが前提です)


Context#openFileOutput()
http://developer.android.com/intl/ja/reference/android/content/Context.html#openFileOutput(java.lang.String,
int)

magpad

unread,
Oct 4, 2010, 1:13:46 AM10/4/10
to 日本Androidの会
リファレンスへのURLが切れちゃいましたね。すみません。

http://developer.android.com/intl/ja/reference/android/content/Context.html
のopenFileOutput()の

The name of the file to open; can not contain path separators.

を参照って意味でした。


On 10月3日, 午後11:32, ロウキル <kkeikm...@gmail.com> wrote:

CLERK

unread,
Oct 4, 2010, 1:40:12 AM10/4/10
to 日本Androidの会
こんちには CLERK と申します。

magpad さんが記載されている通り、「openFileOutput」だとサブディレクトリ等を
含むパス指定ができません。

なので、私がよく開発機以外に対して初回起動時にデバッグ用テストデータ等を展開
する為に行っている方法ですが参考程度に記載させて頂きます。

1.「/data/data/パッケージ名/databases」が存在するかチェック。
2.ディレクトリが存在していない場合は作成する。(作成しないと4でFileNotFoundExceptionが発生します)

以下のような方法で確認と作成が行えます。

File dir = new File(getApplicationInfo().dataDir + "/databases");

if (!dir.exists()) {
dir.mkdirs();
}

3.getAssets().open() で InputStream 取得
4.FileOutputStream を使用してコピー

これで一応 assets からアプリケーションデータディレクトリ以下への
展開が行えます。


On 10月3日, 午後11:32, ロウキル <kkeikm...@gmail.com> wrote:

itog

unread,
Oct 4, 2010, 3:05:37 AM10/4/10
to 日本Androidの会
itogと申します。

既に上がっているアドバイスに加え、assetsに含めるデータサイズ
制限があります。

以前ブログに対策を書いたのでご参考にしてください。
コードもあるのでコピペでだいたいいけると思います。

http://d.hatena.ne.jp/itog/20091228/1262016898

----
itog

ロウキル

unread,
Oct 4, 2010, 7:05:55 AM10/4/10
to 日本Androidの会
こんばんわ。ご回答して頂いたみなさま本当にありがとうございます。
OutputStreamをFileOutputStreamに変えることで無事解決できました。

OutputStreamの第一引数にはパス(/data/等)を指定できなかったのですね。。。
ディレクトリが存在しているかのチェックや、大きなサイズのファイルの分割方法も
大変勉強になりました。ありがとうございました。


On 10月3日, 午後11:32, ロウキル <kkeikm...@gmail.com> wrote:
> }- 引用テキストを表示しない -
>
> - 引用テキストを表示 -
Reply all
Reply to author
Forward
0 new messages