Javaプログラムは、ファイルからテキストを1行ずつ読み取り、新しいテキストを出力ファイルに書き込みます。しかし、BufferedWriter
に書き込むすべてのテキストではありませんプログラムが終了した後、出力ファイルに表示されます。
詳細:プログラムはCSVテキストドキュメントを取得し、それをSQLコマンドに変換して、データをテーブルに挿入します。テキストファイルには、次のような10000行以上が含まれています。
2007,10,9,1,1,1006134,19423882
プログラムは、ファイルをSQLファイルに出力する新しいSQLステートメントを作成する途中でランダムに停止することを除いて、正常に動作するようです。次のようになります。
insert into nyccrash values (2007, 1, 2, 1, 4, 1033092, 259916);
insert into nyccrash values (2007, 1, 1, 1, 1, 1020246, 197687);
insert into nyccrash values (2007, 10, 9, 1
これは、約10000行後に発生しますが、ファイルの終わりまでに数百行あります。ブレークが発生する場所は、1
と,
の間です。ただし、1
を42
に変更すると、新しいファイルに最後に書き込まれるのは4
であり、その整数から2が切り捨てられるため、文字は重要ではないようです。 。そのため、読者または作家は、一定量の書き込み/読み取りを行った後に死にかけているに違いないようです。
My Javaコードは次のとおりです。
import Java.io.*;
public class InsertCrashData
{
public static void main (String args[])
{
try
{
//Open the input file.
FileReader istream = new FileReader("nyccrash.txt");
BufferedReader in = new BufferedReader(istream);
//Open the output file.
FileWriter ostream = new FileWriter("nyccrash.sql");
BufferedWriter out = new BufferedWriter(ostream);
String line, sqlstr;
sqlstr = "CREATE TABLE nyccrash (crash_year integer, accident_type integer, collision_type integer, weather_condition integer, light_condition integer, x_coordinate integer, y_coordinate integer);\n\n";
out.write(sqlstr);
while((line = in.readLine())!= null)
{
String[] esa = line.split(",");
sqlstr = "insert into nyccrash values ("+esa[0]+", "+esa[1]+", "+esa[2]+", "+esa[3]+", "+esa[4]+", "+esa[5]+", "+esa[6]+");\n";
out.write(sqlstr);
}
}
catch(Exception e)
{
System.out.println(e);
}
}
}
残りのデータをフラッシュするOutputStream
を閉じる必要があります。
out.close();
BufferedWriter
のデフォルトのバッファサイズは 8192文字 で、何百行もの未書き込みデータを簡単に保持できる大きさです。
あなたmustclose()
your BufferedWriter
。 close()
your BufferedWriter
はIS-A Writer
であるため、 AutoCloseable
を実装する必要があります。 、つまり(強調が追加された)
不要になったときに閉じなければならないリソース。
flush()
を呼び出す前にBufferedWriter
に対して最初に close()
を呼び出す必要があると言う人もいます。彼らは間違ってる。 BufferedWriter.close()
のドキュメントでは、「ストリームを閉じ、最初にフラッシュする」と強調されています(強調を追加)。
文書化されたフラッシュのセマンティクス( flush()
)は
基礎となるストリームにバッファリングされた出力を書き込むことにより、このストリームをフラッシュします
そのため、close
を使用する必要があり、close
はバッファリングされた出力をフラッシュします。
出力ファイルには、BufferedWriter
に書き込んだテキストの一部が含まれていません。これは、そのテキストの一部がバッファーに保存されているためです。 BufferedWriter
はそのバッファを空にせず、ファイルに渡します。
Java 7なので、AutoCloseable
などのBufferedWriter
リソースが不要になったときに閉じられるようにする最善の方法は、自動リソースを使用することです管理(ARM)、別名 try-with-resources :
try (BufferedWriter out = new BufferedWriter(new FileWriter(file))) {
// writes to out here
} catch (IOException ex) {
// handle ex
}
close
が不要になったらBufferedReader
する必要もあるため、try-with-resourcesブロックをネストする必要があります。
try (BufferedReader in = new BufferedReader(new FileReader("nyccrash.txt")) {
try (BufferedWriter out = new BufferedWriter(new FileWriter("nyccrash.sql"))) {
// your reading and writing code here
}
} catch (IOException ex) {
// handle ex
}
不要になったときに閉じる必要があるリソース。
_finally {
out.close();//this would resolve the issue
}
_
考慮すべき事項:
BufferedWriter.close()
バッファを基礎となるストリームにフラッシュします。したがって、flush()
を忘れて閉じない場合、ファイルにはすべてが含まれない可能性がありますあなたがそれに書いたテキスト。BufferedWriter.close()
は、ラップされたWriterも閉じます。これがFileWriterの場合、これは最終的にFileOutputStream を閉じ、ファイルへの書き込みが完了したことをOSに通知します。close()
を自動的に呼び出します。 OSは幸せになりますが、GCを待つ必要があります。BufferedWriter.close()
は内部文字バッファをクリアするため、BufferedWriter自体がスコープ内に残っている場合でも、ガベージコレクションにメモリを使用できます。つまり、リソースの使用が終わったら、ファイルだけでなくリソースを常に閉じます。
実際に裏を覗きたい場合は、ほとんどのJava APIのソースが利用可能です。BufferedWriterは here です。
コードは、書き込みを終了した後、ライターを閉じているようには見えません。 out.close()
を(できればfinallyブロックに)追加すると、適切に動作するはずです。
bufferedWriterを閉じないで、finallyブロック内で閉じます
finally {
out.close();//this would resolve the issue
}
bufferedWriterを閉じないで、finallyブロック内で閉じます
finally {
out.close();//this would resolve the issue
}
これは動作します。私は同じ問題に直面しており、これは私のために働いた..幸運:)
リソースを使い終わったら、リソース(ファイルだけでなく)を常に閉じてください。
finally {
out.close();//this would resolve the issue
}
ファイルを閉じずにバッファをフラッシュしたい場合があります。これらの状況では、flush-methodを使用できます。
BufferedWriterを使用しているため、必要に応じてバッファーをフラッシュすることもできます。
out.flush()
これにより、残りのバッファが実際のファイルに書き込まれます。また、close-methodはバッファーをフラッシュし、ファイルを閉じます。
out.close()
ファイルを閉じずにバッファをフラッシュしたい場合があります。これらの状況では、flush-methodを使用できます。
行の末尾に\ nを追加する代わりに、BuffredWriterのnewline-methodを使用することもできます。 Newline-methodはシステム固有の行区切り記号を使用するため、コードはさまざまなプラットフォームで動作します。
out.newLine()