Rau-α(Javaです---資源処理においても、日々の生活に醜い?
-
10-07-2019 - |
質問
私たJavaファイルシステムのAPI、下ってきて、以下の機能を使用するコピーのバイナリファイルです。オリジナルのソースから来たのか追加をtry/catch/finallyいただけますようにこすと、バッファームが閉じ、このように、私のOS源の解放前quitingの機能です。
私はグの機能のパターン:
public static void copyFile(FileOutputStream oDStream, FileInputStream oSStream) throw etc...
{
BufferedInputStream oSBuffer = new BufferedInputStream(oSStream, 4096);
BufferedOutputStream oDBuffer = new BufferedOutputStream(oDStream, 4096);
try
{
try
{
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
}
finally
{
oDBuffer.close(); // could throw a IOException
}
}
finally
{
oSBuffer.close(); // could throw a IOException
}
}
私が理解できませんの二 close()
にfinallyで最初の close()
することになるだろうとも、むやみに捨てて、そしてないので実行されます。
私C#の 処分 パターンとして取り扱うことの using
キーワードとなります。
私もよく知らないから、C++のコードされていようなものを使用してJavaのようなAPI):
void copyFile(FileOutputStream & oDStream, FileInputStream & oSStream)
{
BufferedInputStream oSBuffer(oSStream, 4096);
BufferedOutputStream oDBuffer(oDStream, 4096);
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
// I don't care about resources, as RAII handle them for me
}
私は見落とさないよう、またはそれからを演出して醜く、肥大化コードをJavaでの扱いは例外を close()
方法はバッファリングされたストリーム?
より多くのターゲットを教えて私は間違いどこか---)
編集:ではじめましての人ははじめましてアップデートされる際にはこのページでは、私の質問の回答の減少により一点のカップルすか?はいを楽しむ人も多くなremaningす
編集2: マクダウエル 非常に興味深いと感じたんだ。http://illegalargumentexception.blogspot.com/2008/10/java-how-not-to-make-mess-of-stream.html
編集3:以下のマクダウエルのリンクは、私が急落したご提案をJava7のパターンと同様にC#の使用パターン: http://tech.puredanger.com/java7/#resourceblock .私の問題が明示的に記述する。でも、Java7 do
, の問題が残っている。
解決
にされていないたパターンは、正しい方向で取り扱川のほとんどの場合、Java6となります。※
一部を提唱黙って終われている。ご注意このためにこれらの理由 Java:どのような混乱のストリームの取扱い
Java7を紹介 try-with-resources:
/** transcodes text file from one encoding to another */
public static void transcode(File source, Charset srcEncoding,
File target, Charset tgtEncoding)
throws IOException {
try (InputStream in = new FileInputStream(source);
Reader reader = new InputStreamReader(in, srcEncoding);
OutputStream out = new FileOutputStream(target);
Writer writer = new OutputStreamWriter(out, tgtEncoding)) {
char[] buffer = new char[1024];
int r;
while ((r = reader.read(buffer)) != -1) {
writer.write(buffer, 0, r);
}
}
}
AutoCloseable
種類が自動的に閉じ
public class Foo {
public static void main(String[] args) {
class CloseTest implements AutoCloseable {
public void close() {
System.out.println("Close");
}
}
try (CloseTest closeable = new CloseTest()) {}
}
}
他のヒント
問題もあるが、コードまで添い寝のウェブは本当に悪い。
閉じるバッファームストリームを閉じました。●きんでんでいます。すべてのわらせたいあなたはフラッシュを出力ストリームです。もある点を指定すると配下流のためのファイルです。性能面でコピーすバイトの時間(実際にご利用の場合java.ioを使用できtransferTo/transferFromが少し速い).いましたら、それについての変数名を吸います。い:
public static void copy(
InputStream in, OutputStream out
) throw IOException {
byte[] buff = new byte[8192];
for (;;) {
int len = in.read(buff);
if (len == -1) {
break;
}
out.write(buff, 0, len);
}
}
よく使う-つくことができます要因では、"実行"な熟.
私の意見:Javaは為の閉館の資源末ます。であることを追加 private
として単項postfixオペレーターを閉末に囲ます。
あるjava。が反転制御のユーザーのオブジェクトからのオブジェクトの代わりにオブジェクト自体の清掃後そのものです。この残念なことにつながる多くの清掃活動コードに散在するjavaコードです。
C#の"使用"というキーワードを自動的に呼び処分する場合のオブジェクトが範囲外になる.Javaではないことです。
残念ながら、この種のコードがビットの肥大化Java.
この場合の通話oSBuffer.読み込みまたはoDBuffer.書くのが例外をスローし、そのしたいと思うかもしれまでの例外の浸透までの上位の階層となります。
有無防備に電話でclose()内の最後に句を独自の例外で置き換えるための一つのclose()できません。つまり、失敗close()-メソッドを非表示にする独自の例外を作るread()やwrite().そこで、いと思を無視しスローされる例外によりclose()の場合 があった場合に限り その他の方法かったのをスローしません.
この解決を含め、明示的なホース内の内側のみ:
try { while (...) { read... write... } oSBuffer.close(); // exception NOT ignored here oDBuffer.close(); // exception NOT ignored here } finally { silentClose(oSBuffer); // exception ignored here silentClose(oDBuffer); // exception ignored here }
static void silentClose(Closeable c) { try { c.close(); } catch (IOException ie) { // Ignored; caller must have this intention } }
最後に、ファイアーパフォーマンスの経験、コードその仕事のバッファー(複数バイト/read/write).なることにより数が少ない通話はより効率的に追加ファット。