如何有效地附加到大文件。我有一个必须不断附加到文件的过程,并且随着文件大小的增长,性能似乎也变慢了。无论如何要指定一个大的缓冲区大小append
3 回答
虽然 Don 的方法通常是有效的(不过,由于语法错误,它会抛出异常,并且您需要flush()
a BufferedOutputStream
),但我一直计划进一步详细说明(这需要时间)。
Groovy不为 I/O 操作提供特殊对象。因此,您将使用 Java 的FileOutputStream
(用于写入字节)或FileWriter
(用于写入字符串)。两者都提供了一个带有boolean
append
参数的构造函数。
对于这两者,都存在缓冲的装饰器(BufferedOutputStream
和)。BufferedWriter
在这个范围内,“缓冲”意味着内容不一定会立即写入底层流,因此存在 I/O 优化的潜力。
Don 已经为 提供了一个样本,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
类型是相关的。
所以,最后,您可以使用“Groovy 方式”:
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") }
在 Windows 上的 JVM 中,该append
标志已通过查找操作无效地实现。
多次打开文件时,这是更原子的,也不是非常高效。它应该在 Java VM 7 的某个地方修复:http ://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6631352
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()
}