Groovy: добавление в большие файлы - PullRequest
5 голосов
/ 05 ноября 2010

Как эффективно добавлять большие файлы.У меня есть процесс, который должен постоянно добавлять в файл, и с ростом размера файла, производительность, кажется, также замедляется.В любом случае можно указать большой размер буфера с помощью append

Ответы [ 3 ]

13 голосов
/ 05 ноября 2010

Хотя подход Дона является действительным, в целом (однако, он вызовет исключение из-за синтаксической ошибки, и вам необходимо flush() a BufferedOutputStream), я планировал уточнить далее (что требуетего время).

Groovy не предоставляет специальных объектов для операций ввода-вывода.Таким образом, вы бы использовали Java FileOutputStream (для записи байтов) или FileWriter (для записи строк).Оба предоставляют конструктор, который принимает параметр boolean append.
Для обоих существуют декораторы (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 не предоставляет свои собственные объекты ввода / вывода, Groovy JDK (GDK) расширяет несколько типов Java, добавляя удобные методы.В области вывода ввода / вывода релевантны типы OutputStream и File.

Итак, наконец, вы можете работать с этими"Groovy way":

new File("foo").newOutputStream().withWriter("UTF-8") { writer ->
    100.times { writer.write "foo" + it }
}

EDIT: Согласно вашему дальнейшему запросу:

Ни один из методов GDK не позволяет устанавливать размер буфера.

Приведенный выше код Groovy перезапишет файл при повторном вызове.- Напротив, следующий фрагмент кода добавит строку к существующему файлу и, таким образом, можно вызывать повторно:

new File("foo").withWriterAppend("UTF-8") { it.write("bar") }
0 голосов
/ 25 мая 2013

В JVM в Windows флаг append был реализован неэффективно с помощью операции поиска.

Это атомарный сосед или не очень производительный при многократном открытии файла.Это должно быть исправлено где-то в Java VM 7: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6631352

0 голосов
/ 05 ноября 2010
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()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...