Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

PrintWriter#flush

PrintWriter#flush メソッドはどんなときに使うのですか。バッファーを使ってるときですよね。HttpServletResponse#flushBuffer で必要なときに flush していたら特にPrintWriter#flush を使う必要はない。通常は使わない。と考えていいですか?

40

回答

7434

閲覧

40件の回答

評価

0

HttpServletResponseの話なら、そういうことになりますね。

評価

0

すみません、便乗質問なのですが、PrintWriter#closeメソッドはIOExceptionを投げず、内部に保持しているWriterがIOExceptionを投げると、troubleフラグに変換して保持しています。
できればそのままIOExceptionを投げて欲しいのですが、なぜこのようになっているのでしょうか?

評価

0

テキスト出力を担当するというこのクラスの性格からしてそのような実装になっているわけで、それを選んで「そうしないで欲しい」というのは本末転倒な気がします。
それが問題ならこのクラスを使わないか、独自に実装するかを考えるべきでしょう。

評価

0

本当はこう書きたい

================================================================================

public static void close(Closeable c) {
    if (c == null) return;
    try {
        c.close();
    } catch (IOException e) {
        // log
    }
}

================================================================================

上のプログラムはcloseで例外が発生したときにログがとりたいことは明らか
でも、Closeableを実装するクラスが全て例外を発生させるわけではない
本当に発生しないのならいいのだが、例えばPrintWriterは発生した例外を潰してしまう
これにより、上のプログラムでは不十分で、例外を潰す可能性のあるものを調べて、下のように書く必要がある

================================================================================

public static void close(Closeable c) {
    if (c == null) return;
    try {
        if (c instanceof PrintWriter) {
            PrintWriter writer = (PrintWriter) c;
            writer.close();
            if (writer.checkError())
                throw new IOException();
        } else {
            c.close();
        }
    } catch (IOException e) {
        // log
    }
}

================================================================================

instanceofなんて使いたくないのに使わざるを得ない
上のプログラムではcheckErrorメソッドでエラーが発生していることが判明したら例外を投げるようになっているが、この情報はほとんど何の役にも立たない
よって、下のように書ける

================================================================================

public static void close(Closeable c) {
    if (c == null) return;
    if (c instanceof PrintWriter) {
        PrintWriter writer = (PrintWriter) c;
        writer.close();
        if (writer.checkError()) {
            // log
        }
    } else {
        try {
            c.close();
        } catch (IOException e) {
            // log
        }
    }
}

================================================================================

それか、メソッドを分けてしまう方法も考えられる

================================================================================

public static void close(Closeable c) {
    if (c == null) return;
    assert !(c instanceof PrintWriter);
    try {
        c.close();
    } catch (IOException e) {
        // log
    }
}

public static void closePrintWriter(PrintWriter p) {
    if (p == null) return;
    p.close();
    if (p.checkError()) {
        // log
    }
}

================================================================================

とはいえ、一番いいのは例外を内部で変換せずに、そのまま投げてくれること

評価

0

投稿が前後してしまいました・・・
mioさんは仕方ないと考えているようですが、PrintWriterのコンストラクタにはFileを引数にとるものもあります。
テキスト出力のためのクラスだと何がどう本末転倒なのでしょうか?

評価

0

現にそうなっているものにけちをつけても意味がないということです。

PrintWriterを使うか、ライブラリ(?)側でそれを考慮するかはそれぞれの実装者が決めれば良いことです。
様々なケースを考慮するなら、それぞれに応じた処理を書き連ねるのはある意味当たり前でしょう。

それに、staticメソッドでそうしたものを作る設計自体にも違和感を覚えます。

評価

0

mioさんはかなり保守的なんですね。
個人的にはJavaのIO周りの抽象化はかなり失敗していると思うのですが・・・
あと、Closeableインターフェイスはまさに上のようなstaticメソッドを目的として作られたものだったはずです。
そうしたもの、というのが具体的ではないですが、どこに違和感を覚えるかがわかりません。

評価

0

Javaを使わないというのも、ひとつの選択肢ですよ。
言語レベルでも設計レベルでも、目的に合わないなら使わなければいいというだけです。
PrintWriterはあなたの設計思想や目的を考慮して設計されたわけではありません。

評価

0

それは飛躍しすぎでしょう。
そんなことをいっていては、何も使えないことになります。
疑問を投げただけなのに、そこまで言われるとは思っても見ませんでした。
少なくとも、mioさんは私の質問に何一つとしてはっきり答えてもらっていません。

>本末転倒とは?
回答なし

>どこに違和感が?
じゃぁJava使わなければいいじゃん

さらに、
>Closeableインターフェイスはまさに・・・
に対して、
「言語レベルでも設計レベルでも、目的に合わないなら使わなければいい」
というのは全く答になっていませんよね。

>JavaのIO周りの抽象化は・・・
にいたっては、
「PrintWriterはあなたの設計思想や目的を考慮して設計されたわけではありません」
なんて、何が言いたいのかさっぱりな回答です。
そんなことは当然ですよ。では、どのような設計思想や目的を考慮して設計されたんですか?
目的ははっきりしていますが、設計思想は全くわかりません。
mioさんはJava至上主義のようですからそれでもいいかもしれませんが、上でも述べたように、JavaのIO周りの抽象化は失敗していると思うのです。

これだけではまたのらりくらりと交わすだけでしょうから、質問を変えます。

「Closeableインターフェイスは何のためにあるのでしょうか?」
また、
「どのように使うのでしょうか?」

上のようなstaticメソッドが設計思想からして間違っているというのでしたら、もっと有意義な使用方法を教えてもらえないでしょうか?

評価

0

>本末転倒とは?
そうならないように作られたクラスに対してそうなって欲しいと考えているということです。

>どこに違和感が?
こちらが回答なしだったのですけどね。
Closeableはcloseすべきリソースがあると明示するためのものだと考えています。

>というのは全く答になっていませんよね。
>何が言いたいのかさっぱりな回答です。
それぞれ、異なるところへの答えだからですね。

>どのような設計思想や目的を考慮して設計されたんですか?
設計者でない私に言えるのは、特定の人の思想に合致するように作られてはいない、ということだけです。

>mioさんはJava至上主義のようですから
Javaはいくつかの場面で楽だから使っているだけで、Cのほうが好きなのです。

>JavaのIO周りの抽象化は失敗していると思うのです。
そう思うのは自由でしょう。

評価

0

「テキストファイルの中身を全部読み出す処理が、Javaでは面倒くさい」とかは、思わないではないです。

評価

0

やはり新しい質問には答えてくれないのですね。答えられないんですか?

そう思うのは自由といいながら、Javaを使わなければいいとは、矛盾してますね。
そう思った私はあなたに「じゃぁJava使うなよ」と否定されたんですよ?

つまり、
「closeの時のログ?そんなもんとらなきゃいけないのは設計のミスだよ、PrintWriterは例外なんて起きないようにできてんだから、ログなんて必要ないね。取りたきゃ他の言語使えよ」
ってことですね。ははは、冗談がきついなぁ。そんなんで仕事になるわけ無いじゃないですか。

Closeableはcloseすべきリソースがあると明示するためなら、マーカーインターフェイスでいいはずです。
あなたこそ、Javaの設計思想を理解して無いんじゃないですか?

評価

0

そうですね。理解していないのでしょう。

評価

0

>foobar氏

現状が気に入らないのなら、然るべき所に改善要望を出すか、気に入るものを自分で作りましょう。

それだけのことですよ。

もう少し落ちついて書き込みなさることおすすめします。

評価

0

java.io.PrintWriterのクラスコメントには
’エラーが発生したかどうかを知りたければ#checkError()を使ってくれ’
とあるように、クラス仕様自体がjava.ioio.IOExceptionを発生しない
ポリシーで設計されているのです。
例えばjava.io.PrintStreamなんかを見ると同じ設計になっていますが
これが例外を発生するようになっていると、プログラム中の
System.out.print...にすべてtry-catchしなければいけなくなるでしょう。
つまりはWriterクラスの簡易的(非常に曖昧な表現ですが)実装クラスであり
例外の詳細をハンドリングしたければjava.io.BufferedWriterを使うことを
期待しているのでしょう。

評価

0

以下例え話。

刃がギザギザのハサミで紙を切って「切り口の形が孤を描かない。気に入らない!」と言っている人がいました。

それを聞いた人たちが
「そういう風に切れるハサミなんだから。切り口が気に入らないなら違うハサミ使いなよ」
「ナイスな形に切れるハサミを自分で作りなよ」
と思いました。

当然の反応ですね。

評価

0

現状が気に入らないのではなく、そうなっている理由が知りたかっただけです。
上から読んでみてください。
概要は、
「PrintWriterはIOExceptionを投げないけど何で?」
に対して、mioさんが、
「テキスト出力を担当するというこのクラスの性格からしてそのような実装になっているわけで、それを選んで「そうしないで欲しい」というのは本末転倒な気がします。
それが問題ならこのクラスを使わないか、独自に実装するかを考えるべきでしょう。」
と返しました。
はじめからかみ合っていませんね。
というか、mioさんは全く答になっていません。
ここまではいいのですが、そのあとCloseableの例を出したところ、
「staticメソッドでそうしたものを作る設計自体にも違和感を覚えます。」
と、Closeableの意義を一蹴する一言。
で、それはどういうことか聞くと、
「Javaを使わないというのも、ひとつの選択肢ですよ。
言語レベルでも設計レベルでも、目的に合わないなら使わなければいいというだけです。
PrintWriterはあなたの設計思想や目的を考慮して設計されたわけではありません。」
と、全く関係ない話に持っていかれました。つまり、上のCloseableの使い方の使い方は間違ってるけど、どこかは教えてくれないのです。

評価

0

>例えばjava.io.PrintStreamなんかを見ると同じ設計になっていますが
>これが例外を発生するようになっていると、プログラム中の
>System.out.print...にすべてtry-catchしなければいけなくなるでしょう。

そうならないように、例外を発生させない(もしくはRuntimeException系列の例外を投げる)クラス階層があればいいのではないですか?
そこらへん、IO周りの〜という考えに繋がっていきます。
ま、そんなことを言うとまた「じゃぁJavaなんて使うなよ」なんて非建設的な発言がありそうですが。

評価

0

Xさん、Closeableの話は、そのたとえには一致しませんよね。

評価

0

>「PrintWriterはIOExceptionを投げないけど何で?」
そういうものだから。
設計の時点で、あなたの思想は考慮されていないから。

これで満足?

評価

0

私の例え話は、複雑化を防ぐために一連の話題の詳細には一切触れていません。

平たく言うと、「たとえ話に必要ない要素なので無視しました。」

ということでよろしいでしょうか。

評価

0

では、Closeableはどのように使うのが本来正しいのか教えていただけないでしょうか?
今回の件の本質なので、そこは無視できません。

評価

0

本質→一番聞きたい部分
でした。

評価

0

2007-10-02 14:01
>「PrintWriterはIOExceptionを投げないけど何で?」
そういうものだから。

そこは割り切りましょう。PrintWriterであるかどうかは全く問題にしていないことに気付きました。
問題は、Closeableインターフェイスというものがあり、それを上のように使うのは私としてはアリなのですが、mioさんとしてはナシだそうです。
このあたり、私のCloseableに対する理解の足りなさがあるのかもしれません。
そこで、上のCloseableの使い方はどこが間違っているのでしょうか?
どのようにCloseableを使えばいいのでしょうか?
それが知りたいのです。

評価

0

>>「PrintWriterはIOExceptionを投げないけど何で?」
>>そういうものだから。

>そこは割り切りましょう
ちゃんと通じたようなので何より。

closableの件は個人の思想の違いとでもしておけばいいじゃないか。俺はその使い方が悪だとは思わないし。

殊勝な建前並べ立てて回答を要求する様子は見苦しい。

評価

0

個人的にmioさんや他の方の対応はかなり不快に感じたもので。
「なら教えてよ」
といったのですが、誰も教えてくれません。
それが見苦しく感じられたようなら申し訳ありません。
答えられないんだ、ということでここではこれ以上問い詰めないようにします。

評価

0

最後に。
根拠も無いのに回答しないでほしい>mioさん

評価

0

意見の違う人に対して下のような事を言う人間は
まともに相手されなくても仕方ない。

>あなたこそ、Javaの設計思想を理解して無いんじゃないですか?

余計な事を書かなければもう少しまともに相手されただろうにね。もったいない。

評価

0

>できればそのままIOExceptionを投げて欲しいのですが、なぜこのようになっているのでしょうか?

以下、Sunからの回答。
IOExceptionをthrowしていない理由ですが、
(以下略)

評価

0

>どのようにCloseableを使えばいいのでしょうか?
APIドキュメントに書いてあるでしょ。
closeを呼べばいいんですよ。

例外を確実に検知したければ、Print系のストリームは使わないこと。
Print系のストリームはcloseによって閉じられているのか、
閉じられていないのかなんて、知る必要はない。

知りたければ、後から例外をメソッド経由で取得すればいいだけ。
そのためのメソッドがあるでしょ。

そういうガチガチすると面倒なので、
ゆるくしたいというポリシーで作られたAPIに対して、
設計思想を否定するのはどうかと思う。

評価

0

ところでスレ主の「ういす」はありがとうも言えんのかい??

評価

0

言われっぱなし&勘違されたままはいやなので反応。

>知りたければ、後から例外をメソッド経由で取得すればいいだけ。
>そのためのメソッドがあるでしょ。

そんなものはありません。
取得できるのは、何か問題が発生したかどうかだけ。

で、たぶん全部の流れをきちんと追って無いから、

>閉じられていないのかなんて、知る必要はない

やら、

>そういうガチガチすると面倒

やら言えるのでしょうが、それはCloseableがインターフェイスとして機能していないことになりますよね?
Closeableはあなたが言うように、closeを呼ぶだけのものです。
そして、リソースの解放処理には例外は付き物です(このへんからしておかしいのかもしれない。closeがIOException投げないような設計にすればいいだけかも)。
だからそこで失敗した際にログを取ることは簡単に予想できます。
それなのに、その例外を握りつぶし、上のようなコードを書かなければならない。
それを、

>そういうガチガチすると面倒なので、
>ゆるくしたいというポリシーで作られたAPIに対して、
>設計思想を否定するのはどうかと思う。

というのはインターフェイスを否定することになりません?

で、ゆるくしたければ例外を発生しない〜ってのが私の発言にありましたよね。
そちらのほうがゆるくしたいというポリシーで作られたAPIになると思いますよ。
少なくとも、こんな問題は出てこない。

2007-10-02 15:25の指摘に関しては全くその通りでした。
自分がmioさんに「Javaの設計思想を理解して無い」といわれていると解釈したうえでの発言ですが、読み返してみるとそこまでのことは言ってませんね。
その点は申し訳ありませんでした>mioさん

評価

0

2007-10-02 15:37 の良く書き込みされる某人物君、うるさいボケ。

評価

0

mio さん
ありがとう。^^。

評価

0

http://www.javaroad.jp/bbs/bbs_rule.htm
>>2007-10-02 15:52
ガイドライン
掲示板を利用する際の禁止事項  
・ 他人を誹謗・中傷する行為 


わかった??厨さん♪

評価

0

うるさいボケって言うわりには素直に従うんだね。

評価

0

見ない間に話がだいぶ違う方向に…。
フォローしていただいた皆さんには感謝します。

>ういすさん
実際私は、Javaの設計思想について深く勉強してはいません。
ある言語について、さほど精通する気がありませんので。
というわけで、疑問や不信感を深めただけなので、お礼を言われるのも妙な気がしています。

staticメソッドについては、書いておきます。
staticメソッド自体があまりオブジェクティブでないという感覚があり、今回のようなものはそれよりも継承や委譲で同様の処理を作りこむべきではないのか、という違和感です。
なのでインターフェースがどうこうではありませんし、もちろん私の感覚が絶対だというつもりもありません。

評価

0

foobar≠ういす
です。
つまり、staticメソッドを使ってcloseを書くのが駄目だということですね。
ただ、それこそ現実的では無いような気がします。
CommonsのUtils系を見てみると、本来クラスメソッドにあって欲しいものも中にはありますが、基本的にはstaticであることに意味があるものですから。
オブジェクト指向といっても、全てがオブジェクティブに解決できるわけではありませんし、staticメソッドもユーティリティとして使う分には便利に使えると思ってます。

評価

0

私は foobarさんは違います。
最初の mio さんのレスで解決して寝ました。たまたま見たらレスが30ぐらいついていて、、、、、。ということで失礼します。See you ^^

評価

0

すみません、名前を見てませんでした…大変失礼しました。

>CommonsのUtils系を見てみると、本来クラスメソッドにあって欲しいものも中にはありますが、
今回の場合、close()があって他のメソッドが使われないとは思えないというのも、違和感の原因かも知れません。
(CommonsUtilsにそうしたものがないかは、調べてませんが)

staticメソッド自体は、もちろん私もしょっちゅう使っています。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。