WriteFile vs TransmitFile для больших файлов, которые необходимо удалить с сервера после передачи
Я должен инициировать загрузку больших файлов пользователем в веб-браузер, где я создаю файл для передачи на сервер, а затем сразу же удаляю его. Я нашел достаточно примеров, чтобы увидеть, что я, вероятно, должен использовать Response.TransmitFile или Response.WriteFile... но слышал, что есть проблемы с обоими:
WriteFile является синхронным, но он буферизует файл в памяти перед отправкой его пользователю. Поскольку я имею дело с очень большими файлами, это может вызвать проблемы.
TransmitFile не буферизуется локально, поэтому он работает для больших файлов, но он асинхронный, поэтому я не могу удалить файл после вызова TransmitFile. Видимо, очистка файла не гарантирует, что я тоже могу его удалить?
Каков наилучший способ справиться с этим?
Существует также BinaryWrite... Могу ли я пройти через поток файлов, копируя его в сегментах?
4 ответа
Вот хорошее решение, которое использует TransmitFile, но позволяет вам сделать что-то, как только это будет сделано с помощью делегата:
http://improve.dk/blog/2008/03/29/response-transmitfile-close-will-kill-your-application
Просто замените запись в конце на удаление файла.
WriteFile является синхронным, но он буферизует файл в памяти перед отправкой его пользователю. Поскольку я имею дело с очень большими файлами, это может вызвать проблемы.
Я считаю, что вы можете отключить буферизацию для WriteFile, установив Response.BufferOutput = false;
Как только это будет установлено в false, вы сможете вызывать WriteFile без буферизации...
Не могли бы вы зафиксировать файл на диске (случайное имя и т. Д.) И начать отправку, но добавить запись в таблицу БД с временным именем файла, после определенного вами периода времени, выполнить какое-то задание по очистке, просмотреть эти записи БД и удалить файл с диска, если он устарел.
МетодWriteFile используется для загрузки небольшого файла с сервера, параметр size должен находиться в диапазоне от нуля до максимального значения Int32, перед передачей файла он буферизует файл в памяти. Метод TransmitFile используется для загрузки большого файла с сервера, и он не буферизует файл в памяти. Но при попытке удалить файл при загрузке он выдает исключение. Ниже приведен код, который удалит файл после его загрузки.
FileStream fs = new FileStream(@"D:\FileDownLoad\DeskTop.zip", FileMode.OpenOrCreate);
MemoryStream ms = new MemoryStream();
fs.CopyTo(ms);
context.Response.AppendHeader("content-disposition", "attachment; filename=" + "DeskTop.zip");
context.Response.ContentType = "application/octet-stream";
context.Response.BinaryWrite(ms.ToArray());
fs.Close();
File.Delete(@"D:\FileDownLoad\DeskTop.zip");