5

如何有效地附加到大文件。我有一个必须不断附加到文件的过程,并且随着文件大小的增长,性能似乎也变慢了。无论如何要指定一个大的缓冲区大小append

4

3 回答 3

13

虽然 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 输出的范围内,OutputStreamFile类型是相关的。

所以,最后,您可以使用“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") }
于 2010-11-05T10:54:06.560 回答
0

在 Windows 上的 JVM 中,该append标志已通过查找操作无效地实现。

多次打开文件时,这是更原子的,也不是非常高效。它应该在 Java VM 7 的某个地方修复:http ://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6631352

于 2013-05-25T00:32:05.850 回答
0
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()
}
于 2010-11-05T10:14:35.100 回答