Временные, в памяти, файлы на Java

У нас есть система управления контентом, которая позволяет нашим пользователям хранить файлы, загруженные через веб-службу REST. Перед помещением этих файлов в репозиторий их содержимое шифруется.

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

Для этого я в настоящее время сохраняю содержимое во временный файл и передаю временный файл обратно в качестве вложения. Этот подход имел неприятный побочный эффект: ранее зашифрованный файл репозитория хранился «в открытом виде» во временном каталоге.

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

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

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

Есть идеи?

Спасибо!


person Vinnie    schedule 16.06.2011    source источник
comment
Не используйте deleteOnExit — это полезно только для разработки. Он пропускает имя файла до тех пор, пока вся JVM не будет остановлена.   -  person bestsss    schedule 16.06.2011


Ответы (5)


Ну, я думаю, вы могли бы хранить данные в объекте Java, например. HashMap и использовать его в качестве кеша (используйте слабые ссылки, чтобы кеш мог собирать мусор, если сборщик мусора решит это сделать). Если это означает тяжелые последствия для объема используемой кучи, вы можете посмотреть на запуск memcache или эквивалент Java, например. ehcache для хранения ваших объектов вдали от кучи JVM.

Есть ли причина, по которой вы не можете просто передать результат обратно, чтобы, когда он закончился, он был очищен JVM?

person planetjones    schedule 16.06.2011
comment
Это то, что я надеялся сделать (использовать потоки), но не знал, как передать результат обратно через ответ Http. Это возможно? FWIW Я использую Restlet в качестве фреймворка REST WS. - person Vinnie; 16.06.2011
comment
Я думаю, вы просто получите HTTP response.getOutputStream(); напишите на него, а затем сбросьте его. - person planetjones; 16.06.2011
comment
Это так же просто, как передавать байты в поток вывода HttpServletRepose? Может быть, я слишком много думал об этом... спасибо - person Vinnie; 16.06.2011
comment
да, вы просто хотите, чтобы FileInputStream прочитал ваш файл, а затем записал этот поток в OutputStream ответа HTTP. Дайте нам знать, как вы поживаете. - person planetjones; 16.06.2011

Можно ли выбрать Stream? Недостаток в том, что вы храните все в памяти.

person Miki    schedule 16.06.2011
comment
Это то, что я надеялся сделать, но не знал, как отправить результат обратно через ответ Http. Это возможно? FWIW Я использую Restlet в качестве фреймворка REST WS. - person Vinnie; 16.06.2011

Есть ли причина, по которой вам нужно передать объект File обратно, или это то, что вы можете изменить?

Причина, по которой я спрашиваю, заключается в том, что вы можете создать интерфейс с несколькими методами, такими как getName(), getContentStream() и т. д., а затем передать его обратно вместо конкретного объекта File.

person Community    schedule 16.06.2011

не могли бы вы просто сохранить ссылку на чистый временный файл и удалить его, как только шифрование будет выполнено? Возможно, опишите больше ваших процессов, связанных с этим, как то, что делает создание файла?

person iowatiger08    schedule 16.06.2011

Вместо файла вы можете изучить Memcached и удалить файл после его расшифровки.

Кроме того, вы можете просто сохранить зашифрованный файл в базе данных как большой двоичный объект и получить его как поток. Тогда вы сможете расшифровать его на лету.

person John Kane    schedule 16.06.2011