Groovy: добавление к большим файлам
-
29-09-2019 - |
Вопрос
Как мне эффективно добавить к большим файлам. У меня есть процесс, который должен постоянно добавлять в файл, и по мере роста размера файла производительность, кажется, также замедляется. Есть ли в любом случае, чтобы указать большой размер буфера с append
Решение
В то время как Донский подход действителен, в целом (он будет выбрасывать исключение, хотя из-за синтаксической ошибки, и вам нужно flush()
а. BufferedOutputStream
), Я планировал разработать дальше (что требует времени).
Гроовие не предоставляет Специальные объекты для операций ввода / вывода. Таким образом, вы бы использовали 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 }
}
РЕДАКТИРОВАТЬ: Согласно вашему дополнительному запросу:
Ни один из методов 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()
}
В JVM на Windows append
Флаг был реализован неэффективно с помощью операции поиска.
Это соседский атомный и не очень исполнительный при открытии файла несколько раз. Предполагается, что он должен быть зафиксирован где-то в Java VM 7: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6631352.