загрузка огромных файлов - приложение с использованием грааля - PullRequest
0 голосов
/ 25 мая 2011

Я занимаюсь разработкой веб-службы RESTful, которая позволяет пользователям загружать данные в форматах csv и json, которые динамически извлекаются из базы данных.

Сейчас я использую StringWriter для записи данных CSV. Моя главная проблема заключается в том, что набор результатов может быть очень большим в зависимости от пользовательского ввода. В таком случае, мне кажется, что хранить их все в памяти не очень хорошая идея.

Я думаю о создании временного файла, но как сделать так, чтобы файл был удален вскоре после завершения загрузки.

Есть ли лучший способ сделать это.

Спасибо за помощь.

Ответы [ 4 ]

1 голос
/ 26 мая 2011

Если проблема в памяти, вы могли бы просто записать в модуль записи ответов, который пишет непосредственно в выходной поток? Таким образом, вы ничего не храните (много) в памяти и не должны записывать временные файлы:

// controller action for CSV download
def download = {
    response.setContentType("text/csv")
    response.setHeader("Content-disposition", "attachment;filename=downloadFile.csv")
    def results = // get all your results
    results.each { result ->
        out << result.col1 << ',' << result.col2 // etc
        out << '\n'
    }
}

Это записывает в выходной поток, поскольку он зацикливается вокруг ваших результатов.

Теоретически Вы можете сделать это еще более эффективным с помощью памяти с помощью прокручиваемого набора результатов - см. Раздел «Использование прокручиваемых результатов» Запросы с помощью GORM - Критерии - и зацикливание во время записи ответа писатель. Теоретически это означает, что вы также не загружаете все результаты вашей БД в память, но на практике это может работать не так, как ожидается, если вы используете MySQL (и его Java-коннектор). Также может сработать пакетирование запросов вручную (получить строки БД 1-10000, выписать, получить 10001-20001 и т. Д.)

Подобные вещи могут быть более сложными с JSON, в зависимости от того, какую библиотеку вы используете для визуализации ваших объектов.

0 голосов
/ 26 мая 2011

Чтобы создать временный файл, который автоматически удаляется после истечения сеанса, вы можете использовать плагин Session Temp Files .

0 голосов
/ 26 мая 2011

В зависимости от количества задействованных файлов, вы всегда можете использовать http://download.oracle.com/javase/1,5.0/docs/api/java/io/File.html#deleteOnExit(), чтобы гарантировать, что файл будет удален при выключении виртуальной машины.

0 голосов
/ 26 мая 2011

Что ж, самое простое решение для предотвращения слишком долгого хранения временных файлов - это задание cron, которое просто удаляет любой файл во временном каталоге, который имеет измененное время старше, например, 1 часа.Если вы хотите, чтобы все это было выполнено в Grails, вы можете разработать задачу Quartz для очистки файлов.Это задание можно выполнить, как описано выше (и просто проверить временные метки модификации, чтобы решить, что удалять), или вы можете запустить задание только «по требованию» с параметром имени файла, который нужно удалить.После вызова действия загрузки вы можете запланировать очистку этого конкретного файла на X минут позже (чтобы было достаточно времени для успешной загрузки).В этом случае задание будет просто удалять файл.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...