大きなファイルに効率的に追加するにはどうすればよいですか。ファイルに継続的に追加する必要があるプロセスがあり、ファイルサイズが大きくなると、パフォーマンスも低下するようです。とにかく大きなバッファサイズを指定することはありますかappend
3 に答える
Donのアプローチは有効ですが、一般的には(ただし、構文エラーのために例外がスローされ、必要がありますflush()
)BufferedOutputStream
、さらに詳しく説明する予定です(時間がかかります)。
Groovyは、I/O操作用の特別なオブジェクトを提供していません。したがって、Java FileOutputStream
(バイトの書き込みFileWriter
用)または(文字列の書き込み用)を使用します。どちらも、パラメーターを受け取るコンストラクターを提供しboolean
append
ます。どちらの場合も、バッファリングされるデコレータ(および)
が存在します。この範囲での「バッファリング」とは、コンテンツが必ずしも基になるストリームに即座に書き込まれるとは限らないことを意味します。したがって、I/O最適化の可能性があります。BufferedOutputStream
BufferedWriter
のサンプルはすでに提供されていますが、BufferedOutputStream
これがBufferedWriter
:のサンプルです。
File file = new File("foo")
if (file.exists()) {
assert file.delete()
assert file.createNewFile()
}
boolean append = true
FileWriter fileWriter = new FileWriter(file, append)
BufferedWriter buffWriter = new BufferedWriter(fileWriter)
100.times { buffWriter.write "foo" }
buffWriter.flush()
buffWriter.close()
Groovyは独自のI/Oオブジェクトを提供しませんが、Groovy JDK(GDK)は、便利なメソッドを追加することにより、いくつかのJavaタイプを拡張します。I / O出力の範囲では、OutputStream
とFile
タイプが関連しています。
したがって、最後に、これらの「Groovyway」で作業できます。
new File("foo").newOutputStream().withWriter("UTF-8") { writer ->
100.times { writer.write "foo" + it }
}
編集:あなたのさらなる質問に従って:
どのGDKメソッドでも、バッファサイズを設定できません。
上記の「Groovy」コードは、繰り返し呼び出されるとファイルを上書きします。-対照的に、次のコードは既存のファイルに文字列を追加するため、繰り返し呼び出すことができます。
new File("foo").withWriterAppend("UTF-8") { it.write("bar") }
def file = new File('/path/to/file')
// Create an output stream that writes to the file in 'append' mode
def fileOutput = new FileOutputStream(file, true)
// Buffer the output - set bufferSize to whatever size buffer you want to use
def bufferSize = 512
def fileOutput = new BufferedOutputStream(fileOutput, bufferSize)
try {
byte[] contentToAppend = // Get the content to write to the file
fileOutput.write(contentToAppend)
} finally {
fileOutput.close()
}
Windows上のJVMでは、append
フラグはシーク操作で非効率的に実装されています。
これは、ファイルを複数回開く場合、アトミックではなく、パフォーマンスも非常に高くなります。これは、Java VM 7のどこかで修正されることになっています:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id = 6631352