サイトのトップへ戻る

libGDX ドキュメント 日本語訳

サイト内検索

ファイル制御



はじめに

Libgdx アプリケーションは四つの異なるプラットフォーム: デスクトップシステム (Windows, Linux, Mac OS X, headless)、 Android、 iOS、JavaScript/WebGL互換ブラウザ上で動作します。各プラットフォームごとにファイルI/Oの制御は少し異なります。

LibgdxのFiles (コード) モジュールでは以下の機能が使用できます:

  • ファイルからの読み込み
  • ファイルへの書き込み
  • ファイルのコピー
  • ファイルの移動
  • ファイルの削除
  • ファイルとディレクトリの一覧を取得
  • ファイルやディレクトリが存在するかどうか確認

この機能を使用する前に、サポートしている全てのプラットフォームにおけるファイルシステムの考え方の違いを知っておく必要があります。



各プラットフォームのファイルシステム

ここではLibgdx がサポートしているプラットフォームにおけるファイルシステムの考え方を見ていきます



デスクトップ(Windows, Linux, Mac OS X, ヘッドレス環境)

デスクトップ OSでは、ファイルシステムはメモリの大きな塊です。 ファイルは、現在の作業ディレクトリ(アプリケーションが実行されたディレクトリ)からの相対パスか、絶対パスで参照できます。 ファイルパーミッションを無視すれば、ファイルとディレクトリは通常全てのアプリケーションから読み書きできます。



Android

Android の場合は少し複雑です。ファイルはアプリケーションのAPK 内にリソースもしくはアセットとして保存できます。これらのファイルは読み取り専用です。 byteストリームへ直にアクセスでき、伝統的なファイルシステムにとても似ているという理由から、Libgdx ではasset メカニズムのみを使用します。 Resources は一般的なアプリケーションで使う際には便利ですが、ゲームで使う場合は問題が発生します。 例えば、 Android はリソースを読み込む時に自動的に画像のサイズを変更するといったような操作を行ってしまうのです。

アセットは、Android プロジェクトのassets ディレクトリに保存され、アプリケーションを配布する際に自動的にAPK内にパッケージされます。 他のアプリケーションからはこれらファイルにアクセスすることはできません。

ファイルは読み書き可能な内部ストレージに保存することもできます インストールされた各アプリケーションは、アプリケーションごとに専用の内部ストレージを持っています。 このディレクトリは、そのアプリケーションからのみアクセス可能です。このストレージは、アプリケーション用のプライベートな作業領域と考えることができます。

最後に、ファイルはSDカードのような外部ストレージに保存できます。 例えばユーザーがSDカードを取り外すことがあるので、外部ストレージは常に使用できる訳ではありません。 従って外部ストレージへ保存されたファイルについては、存在しないことがある場合を想定してコードを記述する必要があります。 外部ストレージへ書き込みできるようにするためにAndroidManifest.xml ファイルへパーミッションを追加する必要があります。 Permissionsを参照してください。



iOS

iOS では、全てのファイルタイプが使用できます。



Javascript/WebGL

純正の Javascript/WebGL アプリケーションには、従来のファイルシステムの概念がありません。代わりに、画像のようなゲーム素材は複数のサーバ上のファイルを差すURLを使って参照します。 最近のブラウザでは、従来の読み書きファイルシステムに近い ローカルストレージもサポートしています。

Libgdx は、あなたが読み取り専用ファイルシステムについて意識しなくして済むように縁の下で働きます。



ファイル(ストレージ) タイプ

libgdxにおけるファイルは、FileHandle クラスのインスタンスで表されます。 FileHandle はファイルが置かれている場所を定義するタイプを持っています。 以下の表は、各プラットフォームにおける各タイプが使用可能かどうかと保存場所について表しています。

タイプ ファイルパスと機能の説明 デスクトップ Android HTML5 iOS
Classpath Classpath タイプのファイルは、ソースフォルダ内に直接保存されます。これらはjarファイルと一緒にパッケージ化され、常に読み取り専用です。 用途はありますが、このファイルタイプは可能であれば使わないほうが良いでしょう。 使用可 使用可 使用不可 使用可
Internal Internal タイプのファイルは、デスクトップの場合はアプリケーションの ルートディレクトリや 作業ディレクトリからの相対パスの位置、Androidの場合は assetsディレクトリからの相対パスの位置、HTML5の場合はGWT プロジェクトのwar/assets/ディレクトリからの相対パスの位置に保存されています。 これらのファイルは読み取り専用です。内部ストレージでファイルが見つからない場合、fileモジュールはclasspathからファイルを検索する方法に切り替えます。 Eclipseのメカニズムに結びついているasset フォルダを使用する場合は、これが必要です。 詳細は プロジェクト設定を参照してください。 使用可 使用可 使用可 使用可
Local Localタイプのファイルは、デスクトップの場合はアプリケーションの ルートディレクトリや 作業ディレクトリからの相対パスの位置、 Androidの場合はアプリケーションの内部(プライベート)ストレージからの相対パスの位置に保存されます。 デスクトップの場合、Local タイプとinternal タイプの働きはほとんど同じです。 使用可 使用可 使用不可 使用可
External External タイプのファイルは、Android の場合はSD カードのルートからの相対パスの位置、デスクトップの場合はカレントユーザーのホームディレクトリからの相対パスの位置に保存されます 使用可 使用可 使用不可 使用可
Absolute Absolutタイプのファイルには完全修飾パスが指定される必要があります。
注意:移植性を考慮し、このオプションは絶対に必要な場合にのみ使用するようにしてください。
使用可 使用可 使用不可 使用可

Absoluteタイプと classpath タイプのファイルは、より複雑なファイルi/o要件が求められるデスクトップエディタのようなツールで使用されます。 ゲームを作る場合はこれらは無視して構いません。 使用するタイプの優先順位は以下のようになります:

  • Internal Files: アプリケーションにパッケージされた全てのゲーム素材 (画像ファイル、音声ファイルなど)は internal タイプのファイルになります。 セットアップUIを使用する場合は、それらファイルを Android プロジェクトの assetsフォルダに置いてください。
  • Local Files:ゲームの情報を保存するなど、小さなファイルを書き込む必要がある場合は、 local タイプのファイルを使用してください。 これらは、一般的にあなたのアプリケーションでのみ参照できます。 そうではなくキーと値の組み合わせを保存したい場合は、環境設定も参照してください。
  • External Files: スクリーンショットやウェブからダウンロードしたファイルなど、大きなファイルを書き込む必要がある場合は、外部ストレージに保存できます。 ユーザーはあなたが外部ストレージに書き込んだファイルを削除できるため、外部ストレージではファイルが消えてしまう場合があることに気をつけてください ユーザーがアプリケーションをアンインストールしても、これらのファイルは削除されません。 ローカルファイルストレージであれば勝手に削除されることは無いので、通常はそちらを使用するほうが簡単です。


ストレージの可用性とパスを確認する

アプリケーションの動作するプラットフォームによって、使用可能なストレージタイプが異なります。 Files モジュールを使ってこれらの情報を取得できます:

boolean isExtAvailable = Gdx.files.isExternalStorageAvailable();
boolean isLocAvailable = Gdx.files.isLocalStorageAvailable();

外部ストレージと内部ストレージのルートパスも取得できます:

String extRoot = Gdx.files.getExternalStoragePath();
String locRoot = Gdx.files.getLocalStoragePath();


FileHandleを取得する

FileHandle は、上記ファイルタイプのうち一つを使ってFilesモジュールから取得します。 以下のコードでは、internal タイプのmyfile.txtファイルのハンドラを取得します。

FileHandle handle = Gdx.files.internal("data/myfile.txt");

setup UIを使用してプロジェクトを作成した場合は、このファイルはAndroidプロジェクトの assetsフォルダ内(正確には$ANDROID_PROJECT/assets/data)に含まれています。 Eclipseではデスクトップ用プロジェクトとhtml用プロジェクトはこのフォルダーにリンクされており、Eclipseでこのコマンドが実行されると自動的にリンクを追加します

FileHandle handle = Gdx.files.classpath("myfile.txt");

上記の場合の“myfile.txt” ファイルは、コンパイルされたクラスやインクルードされたjarファイルがあるディレクトリに置かれている必要があります。

FileHandle handle = Gdx.files.external("myfile.txt");

上記の場合の“myfile.txt”ファイルは、デスクトップではユーザーの ホームディレクトリ (Linuxの場合は/home/<user>/myfile.txt、Windowsの場合 /Users/<user>/myfile.txt on OSX and C:\Users\<user>\myfile.txt)、AndroidではSDカードのルートに置かれている必要があります。

FileHandle handle = Gdx.files.absolute("/some_dir/subdir/myfile.txt");

absoluteタイプのファイルの handleの場合、 ファイルはフルパスが指し示す正確な位置に置く必要があります。 Windowsの場合はカレントドライブの/some_dir/subdir/ に。linux、 MacOS 、Androidの場合はそのパスが示す正確な位置に。

FileHandle インスタンスは、データの読み書きを司るクラスのメソッドに引数として渡します。 例えば、Texture クラスで画像を読み込む時やAudio モジュールで音声ファイルを読み込む時に、FileHandle は必要です。



一覧取得とファイルプロパティの確認

時には、特定のファイルが存在するか確認したり、ディレクトリの中身の一覧を取得することが必要になります。 FileHandle では、このためのメソッドを簡単に使用できます。

以下の例では、指定したファイルが存在するかどうか、ファイルが実際にはディレクトリなのか否かを確認します。

boolean exists = Gdx.files.external("doitexist.txt").exists();
boolean isDirectory = Gdx.files.external("test/").isDirectory();

ディレクトリ内の一覧取得も同様に簡単です:

FileHandle[] files = Gdx.files.local("mylocaldir/").list();
for(FileHandle file: files) {
   // do something interesting here
}

警告: フォルダを指定しなかった場合、一覧は空になります。

注意:デスクトップでは、 internal でのディレクトリ一覧取得はサポートされていません。

ファイルの親ディレクトリを取得したり、ディレクトリ内のファイル(別名"子")のFileHandle を作成することもできます。

FileHandle parent = Gdx.files.internal("data/graphics/myimage.png").parent();
FileHandle child = Gdx.files.internal("data/sounds/").child("myaudiofile.mp3");

parent"data/graphics/"を指し、child は data/sounds/myaudiofile.mp3"を指します。

FileHandle には、ファイルの特定の属性を確認するメソッドがまだたくさんあります。詳細については Javadocs を参照してください。

注意: 現時点では、これら機能はHTML5 バックエンドではほとんど実装されていません。あなたのアプリケーションがHTML5を対象としている場合は、これらの機能にあまり依存しないようにしてください。



エラー制御

FileHandles でのいくつかの操作は失敗する場合があります。 libGDXでは、例外を投げるのではなくエラーを通知するように RuntimeExceptions を調整しました。 ほぼ90%の状況において、どこにあるのか位置が分かっていて読み取り可能なファイル(例えば、アプリケーションにパッケージされたinternal タイプのファイル)にアクセスするやり方しか使わないからです。



ファイルからの読み込み

FileHandleを取得した後は、それをファイル(例えば、画像)から中身を読み込むことができるクラスに引数として渡すか、自分自身で読み込みを行えます。 後者の方法については、FileHandleクラスの任意の入力メソッドを使って行えます。 以下の例では、internalタイプのファイルからテキストを読み込む例を示しています:

FileHandle file = Gdx.files.internal("myfile.txt");
String text = file.readString();

バイナリデータを持っている場合は、ファイルを簡単に {{{byte[]}}}配列へ読み込めます:

FileHandle file = Gdx.files.internal("myblob.bin");
byte[] bytes = file.readBytes();

FileHandle クラスはさらに多くの読み込みメソッドを持っています。詳細情報については Javadocs を確認してください。



ファイルに書き込む

ファイルの読み込みと同様に、FileHandle ではファイルへの書き込みメソッドも使用できます。 local、external、absoluteのファイルタイプでのみファイルへの書き込みをサポートしているので注意してください。 ファイルへ文字列を書き込む処理は、以下のように行います:

FileHandle file = Gdx.files.local("myfile.txt");
file.writeString("My god, it's full of stars", false);

FileHandle#writeStringの二番目の引数は、この内容を ファイルに追加するかどうかを指定しています。 falseが設定された場合、現在ファイルに保存されている内容に上書きします。

もちろん、バイナリデータをファイルに書き込むこともできます:

FileHandle file = Gdx.files.local("myblob.bin");
file.writeBytes(new byte[] { 20, 3, -2, 10 }, false);

FileHandleには、例えばOutputStreamを使用するといったような、書き込みを簡単に行えるメソッドが他にもたくさんあります。 これについても、詳細は Javadocs を参照してください。



ファイルとディレクトリの削除、コピー、名前変更、移動

これらの操作についても、書き込み可能なファイルタイプ(local, external, absolute)でのみ使用可能です。 ですが、読み込み専用のFileHandleでもコピー操作でのコピー元として使用することはできるので覚えて置いて下さい。 以下いくつかの操作例です:

FileHandle from = Gdx.files.internal("myresource.txt");
from.copyTo(Gdx.files.external("myexternalcopy.txt"));

Gdx.files.external("myexternalcopy.txt").rename("mycopy.txt");
Gdx.files.external("mycopy.txt").moveTo(Gdx.files.local("mylocalcopy.txt"));

Gdx.files.local("mylocalcopy.txt").delete();

ファイルとディレクトリを、操作元や操作先に指定できます。

使用可能なメソッドの詳細情報については、FileHandle の Javadocsを確認してください。