Удалить загруженный файл, если он не перемещен в другую папку

Я разрабатываю систему комментариев с asp.net. Пользователь может прикрепить изображение с помощью кнопки «Прикрепить» и опубликовать комментарий с помощью кнопки «Опубликовать». Загрузка изображения начинается, когда пользователь прикрепляет его. Обработчик ASHX сохраняет загруженный файл в папку «temp». Если пользователь нажимает кнопку «Опубликовать», я перемещаю изображение в безопасное место. Если он не нажимает «Опубликовать», закрывает браузер и уходит, файл остается в папке «temp». Как я могу удалить файл из этой «временной» папки через час после его загрузки?

Подробности. Я думал об использовании System.Timers.Timer в файле ashx, используемом для загрузки

System.Timers.Timer timer = new System.Timers.Timer(300);
string fileName;

public void Cleaner()
{
    System.Timers.Timer timer = new System.Timers.Timer(300); //3 second
    timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
    timer.Start();
}

protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs a)
{
    timer.Stop();
    timer.Close();

    string path = "temp";
    string mapPath = HttpContext.Current.Server.MapPath("../" + path);
    FileInfo TheFile = new FileInfo(mapPath + "\\" + fileName);
    if (TheFile.Exists) File.Delete(mapPath + "\\" + fileName);
}

public void ProcessRequest(HttpContext context)
{
    //Saving uploaded file
    Cleaner();
}

но чувствую, что делаю не так.

Таймер срабатывает через 3 секунды, но HttpContext.Current в функции timer_Elapsed() возвращает значение null. Кроме того, имя файла также возвращает null после срабатывания таймера. Я не смог найти способ передать имя файла в качестве параметра при привязке события. Просто, это проблематично. Я ищу более элегантный способ удалить загруженный файл через час.


person sevenkul    schedule 21.12.2011    source источник


Ответы (2)


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

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

LMK, если вам нужны указатели кода.

person Myles McDonnell    schedule 21.12.2011
comment
Я выгляжу хорошей идеей, но я еще не мог ее осмыслить. Я не знаю, можно ли получить время истечения сеанса. - person sevenkul; 21.12.2011
comment
Посмотрите в Global.asax, там есть обработчик, который вызывается, когда сеанс истекает. В этом обработчике вы можете получить те файлы, которые были загружены, но не отправлены из сеанса, и попросить процесс очистки удалить их. Каждый раз, когда процессу очистки предлагается очистить файлы, он также должен искать потерянные файлы (те, у которых нет сеанса, поскольку они, возможно, не были очищены из-за сбоя/перезапуска приложения). - person Myles McDonnell; 21.12.2011

HttpContext.Current должен быть нулевым, так как контекст умер как только был отправлен ответ.

Если бы вы использовали unix, я бы посоветовал написать скрипт и запустить его с помощью cron. Но, похоже, вы используете Windows.

Итак, напишите программу (exe), которая удаляет файлы (а лучше только файлы изображений) из временного каталога на основе даты создания. Google, и вы найдете много учебников, как это сделать. Удаление файла — это одна строка кода. Если вы используете системный временный каталог, это еще одна строка кода. Если вы используете пользовательский временный каталог, вы уже знаете путь. Если вы хотите проверить свойство времени создания (или свойство времени последнего изменения), вам нужно написать еще несколько строк.

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

person Sarwar Erfan    schedule 21.12.2011
comment
Проблема с этим подходом заключается в том, что сеанс, который загрузил файл, может все еще быть активным, поэтому пользователь может по-прежнему захотеть опубликовать его. Простое удаление файла из-за того, что ему один час, — ошибочная логика. - person Myles McDonnell; 21.12.2011
comment
определение ошибочной логики ПОЛНОСТЬЮ зависит от бизнес-логики. Я надеюсь, вы понимаете. 1 час не высечен в камне, это соответствует бизнес-логике. - person Sarwar Erfan; 21.12.2011
comment
Я, вероятно, не буду аутентифицирован, чтобы запланировать задачу на машине, которую я буду использовать. - person sevenkul; 21.12.2011
comment
@ Сарвар Эрфан, согласен. но любая логика, которую вы придумаете, должна будет учитывать живые сеансы и, следовательно, потребует межпроцессного взаимодействия. Если вы не установите очень большое время жизни, скажем, 1 неделю, но это может быть проблемой, если сайт имеет большой объем. - person Myles McDonnell; 21.12.2011