- ベストアンサー
ファイルの書き出し方法について
- ファイルの出力方法についての質問です。
- inputstreamからファイルを作成する際、より高速に行う方法はありますか?
- streamから直接ファイルに書き出す方法はないでしょうか?
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
いろいろと指摘できる点がありますね。 まず、何度も文字列の連結作業をしたい場合、 tmp = tem + str; や tem += str; のように、+ 演算子を使うのは禁じ手です。一度文字列を連結するたびに、文字列のインスタンスが作られるからです。このような場合は、StringBuffer を用意しておいてそれに文字列を追加するようにし、最後に一度だけ文字列に変換します。 また質問文を見る限り、すべてのデータを読み取ってから一気にファイルに出力しているようですが、それではデータを一時的に保存するためにメモリを多く消費してしまいます。少し読み取って少し書き出し、を繰り返すようにすると、効率的です。 最後に、本当に InputStreadReader やバッファを使う必要があるか、ということです。ただ単に URL にあるファイルをダウンロードするだけなら、いちいちバイト列を文字に変換する必要はありません。バイト列を読み込んだら、そのままバイト列を出力すればよいのです。バイト列から文字に変換する際に余計な時間がかかりますし、質問文にあるプログラムでは読み込んだデータが文字化けする可能性が非常に高いです。 (安易に InputStreamReader を使ってはいけません。エンコードを指定しない場合、実行時の環境のデフォルトのエンコードを使ってバイト列から文字に変換されます。もしバイト列の内容とエンコードが違っていたら……) また、InputStream から OutputStream へデータを渡す際の処理が必然的にバッファの意味を持つので、無理にほかにバッファを作る必要はありません。 例(動作確認してません) URL myURL = new URL("欲しいページ"); File myFile = new File("保存先ファイル"); InputStream in = myURL.openStream(); OutputStream out = new FileOutputStream(myFile); byte[] bytes = new byte[8192]; int n; // 少し読み取って少し書き出す、を繰り返す。 // これが「ストリームからストリームへ直接渡す」感じです。 while ((n = in.read(bytes)) >= 0) { out.write(bytes, 0, n); } in.close(); out.close();
お礼
早速のご回答有り難うございます。 また詳細にわたる説明をいただき有り難うございました。 サンプルで頂いた方式でやってみたところ動きました。 sreamからsteamに直接渡すというイメージも分かりました。 まさしく私がイメージしていた通りです。 自分でもStringに変換してからやるやり方に疑問を抱いていたのですが かといってどうやってやったらいいのかもわからず困っていました。 これから 私方式と教わった方式でどのくらい実行速度が変わるのか実験してみます。 速度的な無駄だけが省けたわけではないとは思いますが Stringに直していた無駄な処理は時間計測が可能かと思われますので。 有り難うございました。