3

今日、ハードディスク上にあるファイルに情報を書き込んでいるある種のサーブレットで作業していたとき、次のコードを使用して書き込み操作を実行していました。

 File f=new File("c:/users/dell/desktop/ja/MyLOgs.txt");
        PrintWriter out=new PrintWriter(new FileWriter(f,true));
        out.println("the name of the  user is "+name+"\n");
        out.println("the email of the user is "+ email+"\n");
        out.close();             //**my question is about this statement**

ステートメントを使用していないとき、サーブレットは正常にコンパイルされていましたが、ファイルには何も書き込まれていませんでしたが、それを含めると、書き込み操作は正常に実行されました。私の質問は次のとおりです。

  1. そのステートメントを含めなかったときにデータがファイルに書き込まれなかったのはなぜですか(サーブレットでさえエラーなしでコンパイルされていました)?
  2. ストリームのクローズ操作はどの程度まで重要ですか?
4

6 に答える 6

4

呼び出すclose()と、すべてのデータがフラッシュされます。自動フラッシュ(コンストラクPrintWriterターの1つに対する2番目の引数)を有効にせずにを作成しました。flush()これclose()は、手動で呼び出す必要があることを意味します。

閉じると、ファイルを開いて使用していたシステムリソースも解放されます。VMとオペレーティングシステムは最終的にファイルを閉じますが、コンピュータのメモリを節約するために、ファイルの使用が終了したらファイルを閉じることをお勧めします。

また、常に呼び出されるように、ブロックのclose()内側に配置することもできます。そのような:finally

PrintWriter out = null;
try {
    File f = new File("c:/users/dell/desktop/ja/MyLOgs.txt");
    out = new PrintWriter(new FileWriter(f,true));
    out.println("the name of the  user is "+name+"\n");
    out.println("the email of the user is "+ email+"\n");
} finally {
    out.close();
}

参照:PrintWriter

Sanchitは、Java 7 VMがストリームを自動的に必要としないときに、ストリームを自動的に閉じるようにすることについても良い点を示しています。

于 2013-01-06T15:06:34.750 に答える
3

を実行closeするPrintWriterと、データを移動したい場所にすべてのデータがフラッシュされます。何かに書き込むたびにこれを行うと、書き込みは簡単なプロセスではないため、非常に非効率になるため、これは自動的には行われません。

で同じ効果を達成できflush();ますが、常にストリームを閉じる必要があります。http://www.javapractices.com/topic/TopicAction.do?Id = 8およびここ:http : //docs.oracle.com/を参照してください。 javase / tutorial / jndi / ldap/close.html。ストリームの使用が終了したら、必ずストリームを呼び出しclose();てください。さらに、例外に関係なく常に閉じられるようにするには、次のようにします。

try {
    //do stuff
} finally {
    outputStream.close():
}
于 2013-01-06T15:06:03.490 に答える
2

これは、PrintWriter書き込み操作ごとにI / O操作を繰り返し行わないようにするためにデータをバッファリングするためです(これは非常にコストがかかります)。close()バッファを呼び出すと、ファイルにフラッシュされます。flush()ストリームを閉じずにデータを強制的に書き込むように要求することもできます。

于 2013-01-06T15:05:52.567 に答える
2

ストリームは、閉じる前にデータを自動的にフラッシュします。したがって、を使用して時々手動でデータをフラッシュするか、使いout.flush();終わったらストリームを閉じることができます。プログラムが終了すると、ストリームが閉じてデータがフラッシュされます。これが、ほとんどの場合、人々がストリームを閉じない理由です。

Java 7を使用すると、以下のような操作を実行できます。これにより、ストリームを開いた順序で自動的に閉じます。

public static void main(String[] args) {
  String name = "";
  String email = "";
  File f = new File("c:/users/dell/desktop/ja/MyLOgs.txt");
  try (FileWriter fw = new FileWriter(f, true); PrintWriter out = new PrintWriter(fw);) {
    out.println("the name of the  user is " + name + "\n");
    out.println("the email of the user is " + email + "\n");
  } catch (IOException e) {
    e.printStackTrace();
  }
}
于 2013-01-06T15:12:51.140 に答える
1

PrintWriter書き込まれるデータをバッファリングし、バッファがいっぱいになるまでディスクに書き込みません。を呼び出すclose()と、残りのデータが確実にフラッシュされ、が閉じられますOutputStream

close()ステートメントは通常、finallyブロックで表示されます。

于 2013-01-06T15:07:19.757 に答える
0

そのステートメントを含めなかったのに、なぜデータがファイルに書き込まれなかったのですか?

プロセスが終了すると、管理されていないリソースが解放されます。InputStreamsの場合、これは問題ありません。OutputStreamsの場合、バッファリングされたデータが失われる可能性があるため、プログラムを終了する前に、少なくともストリームをフラッシュする必要があります。

于 2013-01-06T15:20:35.490 に答える