fc2ブログ
ヽ|∵|ゝ(Fantom) の 開発blog? ホーム »テキストファイル読み込み
このページの記事一覧

【Applet】【Java】jar 内リソースからテキストファイルを読み込む  


これも簡単。これまでの以下のコードを組み合わせるだけでできる。コピペで構わない。

getJarFileURL() - クラスから自身の jar の URL を取得する
toJarURL() - jar 内のリソースを取得する
loadText() - ストリームからテキストファイルを読み込む

実行は前回同様 Applet で Web ページから、.jar で起動してることを想定している。読み込むファイルが、Web サーバ上から、 jar 内リソースに変わっただけだ。

//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード

//jar ファイル内から、テキストファイルを読み込む
public static final String loadTextJar(String fileName, Object context) throws IOException, FileNotFoundException {
final String jarUrl = toJarURL(fileName, context);
if (jarUrl == null) { //見つからないとき
throw new FileNotFoundException();
}
final URL url = new URL(jarUrl);
InputStream is = url.openStream();
return loadText(is, DEFAULT_ENCORDING);
}

//メインでは... (※例外処理は省略)
String fileName = "res/data/sample.txt"; //jar 内相対パス
String text = loadTextJar(fileName, this); //this は起動した Applet オブジェクトが良い

//System.out.println(text);
//↑では確認しずらいので、↓のメソッドなどで確認
public void paint(Graphics g) {
g.drawString(text, 5, 25);
}

内容的には前回の「URL経由でWebサーバ上のテキストファイルを読み込む」とほとんど変わらない。toJarURL() から null が返って来た時、わかりやすいように FileNotFoundException() を throw しているが、特に何でも構わない。

これで jar ファイル内に小さな設定ファイルなどを置いて、読み込んで行く事もできる。
ストリームを開いて、loadText() に投げるという基本は変わらない。

次回からは同じ要領で Android でのテキストファイルの読み込みを考えてみよう。





(関連記事)
【Applet/汎用】URL経由でWebサーバ上のテキストファイルを読み込む
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【汎用】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【汎用】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する



関連記事

category: Applet

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み 
tb: 0   cm: --

【Applet】【Java】URL経由でWebサーバ上のテキストファイルを読み込む  


Android でも使えるhttpダウンロード方式は→こちら

前回の続き。というか使い回しもテーマの内なので、2つの関数

readStream() - ストリームから読み込み、バイト配列で返す
loadText() - ストリームから読み込み、テキストエンコードして返す


は、そのまま使う。

今回は URL 経由で同 Web サーバ上のテキストファイルを読み込む方法。もちろんブラウザのアクセスと同じ仕様になるわけで、ファイルの読み取りパーミッションやディレクトリの閲覧権限なども関係するが、とりあえずそれらはOKの状態を前提としてコードを書いてみる。ストリームから読み込むルーチンは前回完成してるので、それを使えばもの凄く簡単だ。実行は Applet で Web ページから 、.class や .jar から起動してることを想定している。

//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード

//URL経由でWebサーバ上のテキストファイルを読み込む
public static final String loadTextURL(URL url) throws IOException {
InputStream is = url.openStream(); //url.openConnection().getInputStream() と同じ
return loadText(is, DEFAULT_ENCORDING);
}

//メインでは... (※例外処理は省略)
String fileName = "res/data/sample.txt"; //html からの相対パス
String text = loadTextURL(new URL(getCodeBase(), fileName)); //同サーバ上の場合

//System.out.println(text);
//↑では確認しずらいので、↓のメソッドなどで確認
public void paint(Graphics g) {
g.drawString(text, 5, 25);
}

同 Web サーバ上の自アプリ用のテキストファイルを読み込んでることを想定しているので、getCodeBase() を使っているが、別サーバで "http://~" の指定でも構わない。ただしその場合は、アクセス権限や、サーバによってはクロスドメインの設定など必要になるかもしれない。

(参考) クロスドメインのセキュリティ・モデル
(参考) クロスドメインポリシーファイル
(参考) カスタムポリシーファイル

また同サーバ上でないなら、本来はこの readStream() のように一気に読み込み、全ての文字エンコーディングしていくタイプより、通信しながら随時文字エンコーディングしていくコードの方が良いだろう。その場合は InputStreamReaderBufferedReader を使った方が良い。~Reader クラスというのは言わば、通常の ~Stream 関連クラスに順次文字エンコーディングしていく機能を付け加えたものと考えれば簡単だ。また別サーバとの通信は、片方のサーバダウンやアクセス障害なども考慮に入れて、通常は別スレッドにして、メインでは進捗を表示する事が多いね。そうでないと、いつの間にかどちらかのサーバがダウンなどして、いつまでも待ち状態になり兼ねない。タイムアウト機能も必要だろう。小さなファイルならそれほど問題もないが、大きなファイルには向かない。同サーバ上なら、起動ファイルも一緒に落ちるので、見た目でわかりやすい分、そこまで神経質になる必要もないが(笑)。

これでサーバ上に小さな設定ファイルなどを置いて、読み込んで行く事もできる。

次回は jar 内のリソースからテキストファイルを読み込んでみよう





(関連記事)
【Java】【PHP】【JSON】JSON を PHP から送信して、Java で受信する
【Applet】jar 内リソースからテキストファイルを読み込む
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【汎用】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【汎用】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する


関連記事

category: Applet

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み 
tb: 0   cm: --

【Android】【Applet】【Java】ストリームからテキストファイルを読み込む  


 以前の「テキストファイルを読み込む」では、あくまでもテスト的なコードだったが、今度はより実用的なコードを書いてみる。なるべく汎用性を持たせるために、まず手始めにストリームから読み込むルーチンを作成する。本来ならパフォーマンスやエンコードなど、環境によってその都度最適化すべきだろうが、とりあえず何にでも使えそうなデフォルト値を決めて置くので、必要ならば、適当に修正すると良いだろう。

 ストリームの説明は割愛するが、以下のHPなどが分かり易いだろう。今回はテキストファイルをテーマにしてるが、ストリームの概念を覚えてしまえば、色々なファイルが読み込める。今回のコードも様々なデバイスから読み込むために、わざと機能分割して、いくつかのメソッドに分けてある。用途によってまとめても良いが、たぶんこれくらいの単位の方が、後々色々組み合わせて使うのには便利だろう。

(参考) ストリーム
(参考) バッファ入出力

//設定値
private static final String DEFAULT_ENCORDING = "UTF-8"; //デフォルトのエンコード
private static final int DEFAULT_READ_LENGTH = 8192; //一度に読み込むバッファサイズ

//ストリームから読み込み、バイト配列で返す
public static final byte[] readStream(InputStream inputStream, int readLength) throws IOException {
final ByteArrayOutputStream byteStream = new ByteArrayOutputStream(readLength); //一時バッファのように使う
final byte[] bytes = new byte[readLength]; //read() 毎に読み込むバッファ
final BufferedInputStream bis = new BufferedInputStream(inputStream, readLength);

try {
int len = 0;
while ((len = bis.read(bytes, 0, readLength)) > 0) {
byteStream.write(bytes, 0, len); //ストリームバッファに溜め込む
}
return byteStream.toByteArray(); //byte[] に変換

} finally {
try {
byteStream.reset(); //すべてのデータを破棄
bis.close(); //ストリームを閉じる
} catch (Exception e) {
//IOException
}
}
}

//ストリームから読み込み、テキストエンコードして返す
public static final String loadText(InputStream inputStream, String charsetName)
throws IOException, UnsupportedEncodingException {
return new String(readStream(inputStream, DEFAULT_READ_LENGTH), charsetName);
}


//ローカルシステムから、テキストファイルを読み込む
public static final String loadTextLocal(String fileName) throws IOException, FileNotFoundException {
InputStream is = new FileInputStream(fileName);
return loadText(is, DEFAULT_ENCORDING);
}

//メインでは... (※例外処理は省略)
String fileName = "C:/res/data/sample.txt"; //相対パスでも良い
String text = loadTextLocal(fileName);
System.out.println(text);


 とりあえず、サンプルにローカルシステム(Windows 等)からテキストファイルを読み込むメソッドを並べてみた。例外処理は省略してある。ファイル処理の場合、おおよそ、FileNotFoundException, IOException がほとんどだろう。

 エンコードはデフォルトで "UTF-8" にしてあるが、"Shift_JIS" などにもできる。しかし、今後の事を考えるとすべて "UTF-8" にして置いた方が無難だろう。ちなみに Charset クラスで Charset.forName(charsetName) のように動的に引数を適正化することも考えたが、Android では String 変換時に上手く行かなかった。あまりいじることがないなら、文字列定数で十分だろう。

 readStream() では、8192 byte ずつ読み込むようにしてあるが、この辺りは環境によって違うかもしれない。Android 開発では Eclipse が 8K にしろと言っていたのでそうした(笑)。だがまぁ、ほとんどのシステムでも問題ないサイズだと思う。

 ByteArrayOutputStream というのはバイトストリームを一時バッファのように使うために、わざわざ生成している。あまりに巨大なファイルでなければ、メモリの許す限り自動的にバッファを拡張してくれるので採用した。バイト配列で返すので、実はテキストでなくても、画像でも音声でも構わない(別途デコードが必要になるが)。ストリームさえオープンしてしまえば、何でも良いので、独自データの読み込みなどにも使えるだろう。そのため、loadText() と分けてある。また読み込み終わったらバッファは破棄し、ストリームはクローズしてる。つまり開きっぱなしの連続使用は想定してない。

 少し細かくわけてしまったが、これからこのメソッドを使い回しして、様々なテキストファイルを読み込む関数を作ってみよう。ここまで出来てしまえば、流用は非常に簡単だ。

 次回は同 Web サーバ上にあるテキストファイルを読み込んでみよう


(関連記事)
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【Applet/汎用】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Android】Preference 機能を使ってデータを読み込み・保存する



関連記事

category: Android

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み 
tb: 0   cm: --

【Java】【Android】テキストファイルを読み込む  


 Java のファイル読み込みはわかりずらいね。Java の欠点としてクラスが多すぎ(笑)。抽象クラスも含むから初めは何を使ったらいいかわからない。

※Android の各デバイスなどで使えるように、ライブラリ化したものをまとめたものは → こちら

 おおまかには、InputStream, FileInputStream, InputStreamReader, FileReader, BufferedReader などを使う。他にも色々あるけど、とりあえずこのあたりを理解すれば使える。違いを理解するために、わざと色々な書き方をしてみる。仕様としては、前回の StreamTokenizer とほとんど同じ。適当にファイルを読み込んで表示するだけだ。

public void readFileTest(String fileName) {
//ファイル名から File オブジェクトを生成
File file = new File(fileName);

//raw バイトのストリームをオープン
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
return;
}

//バイトストリームから文字ストリームへ変換
InputStreamReader isr = null;
try {
isr = new InputStreamReader(fis, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
if (fis != null) {
try {
fis.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
return;
}

//バッファリングしながら読み込むReader
try {
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}

//メインではファイル指定のみ
String fileName = "C:/test/sample.txt";
readFileTest(fileName);

 長いね・・・。わざと例外処理を細かく入れてるけど、1つ1つやっていくと本当に長い。要するに入力ストリームを開いて、文字エンコードストリームを中継、それを1文字ずつ読み込むのは効率悪いので、バッファリングしながら1行ごとに一気に表示、って感じ。FileInputStream はそのまま InputStream に置き換えられる。

 少し長いので例外処理を手抜きしてまとめてみる。メインは同じ。

public void readFileTest(String fileName) {
try {
FileInputStream fis = new FileInputStream(fileName); //raw バイトのストリームをオープン
InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); //バイトストリームから文字ストリームへ変換
BufferedReader br = new BufferedReader(isr); //バッファリングしながら読み込むReader
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

 随分短くなって機能がわかりやすい。FileInputStreamFile オブジェクトにしなくても直接ファイル名でもいいので、省略。
 あとは開いた FileInputStreamInputStreamReader も途中で変えることはないので、これも無理矢理まとめてみる。

public void readFileTest(String fileName) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(fileName), "UTF-8"));
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

 もう1つ、FileReader という文字ストリーム用のクラスがあって、これはデフォルトのエンコードで良い場合や byte バッファのサイズが適切に設定されているときに、InputStreamReaderFileInputStream をまとめたようなものになってる。エンコードは UTF-8 と決まっていて、バッファは BufferedReader にお任せなら、上記のコードをショートカット的に使うこともできる。

public void readFileTest(String fileName) {
try {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}

 はじめからすると、半分以下のコードになったね(笑)。自分で使う分にはこれでも良いかも。でもこれは例外処理が分岐されてないので、汎用的には向かないかもね。まぁ、実際には一番多いのが「ファイルが見つからない(FileNotFoundException)」であって、IOException はローカルならあまり出ない気もするが・・・。ネット経由なら別だけどね。

 ストリームのクローズ状態が心配なら、finally ブロックにするのもいいかもね。

public void readFileTest(String fileName) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(fileName));
String line;
while ((line = br.readLine()) != null) { //1行ごとに読み込む
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}

 今度はちょっと長くなったが、close() は既に閉じられているときは何もしないので、ここまでやっておけば、とりあえずどこでエラー出ても心配はないかもしれない。

 あとは、例外処理を throws を使ってメインに投げてしまう手もあるね。ただし、メインでは例外処理が必要になるわけだが・・・。

public void readFileTest(String fileName) throws IOException, FileNotFoundException {
BufferedReader br = new BufferedReader(new FileReader(fileName));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}

//メインでは例外処理が必要
String fileName = "C:/test/sample.txt";
try {
readFileTest(fileName);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

 メソッドはわずか数行(笑)。書き方は千差万別だね。用途に応じて変えるのも良いかも。ちなみに1行ごとではなく、1文字ずつ読み込みたい場合は、while の部分を、

int ch;
while ((ch = br.read()) != -1) { //1文字ずつ読み込む
System.out.print((char)ch);
}

に置き換えればいい、Android の assets から読み込んで使いたい場合は前回と同じように、AssetManager からストリームをオープンして、一番最初の例の InputStreamReader につっこめばそのまま使える。基本が分かれば同じようなもんだね。これでシナリオ読み込みなどにも使えるね。

(関連記事)
【Android】【Applet】【Java】テキストファイルの読み込み・保存 まとめ
【Java】ストリームからテキストファイルを読み込む(ストリームから読み込み、テキストエンコードして返す)
【Android】res/raw リソースフォルダからテキストファイルを読み込む
【Android】assets フォルダからテキストファイルを読み込む
【Android】内部ストレージからテキストファイルを読み込む
【Android】内部ストレージにテキストファイルを保存する
【Android】SDカードからテキストファイルを読み込む
【Android】SDカードにテキストファイルを保存する
【Android】エラーをSDカードに書き出す
【Java】ローカルシステム(Windows 等)から、テキストファイルを読み込む
【Applet】URL経由でWebサーバ上のテキストファイルを読み込む
【Applet】jar 内リソースからテキストファイルを読み込む
【Java】JSON を PHP から送信して、Java で受信する


関連記事

category: Java

thread: プログラミング

janre: コンピュータ

tag: テキストファイル読み込み 
tb: 0   cm: --


プロフィール

Social

検索フォーム

全記事一覧

カテゴリ

ユーザータグ

最新記事

リンク

PR

▲ Pagetop