Mit ASP.NET respektive C# eine Datei zum Client zu streamen, ist kein großes Problem. Das macht man zum Beispiel, wenn man die Datei nicht direkt zum Download anbieten möchte, weil man sie vielleicht nur für eingeloggte Benutzer bereitstellen oder die Anzahl der Downloads mitloggen möchte.
Problematisch kann es allerdings immer dann werden, wenn mehrere Benutzer gleichzeitig versuchen, die Datei herunterzuladen, vielleicht sogar in verschiedenen von einander unabhängigen Anwendungen. Die Folge ist eine IOException mit dem schönen Text:
Der Prozess kann nicht auf die Datei D:\xyz.pdf zugreifen, da sie von einem anderen Prozess verwendet wird.
Ein Lösungsansatz, der sich anbietet, ist es diesen Ausnahmefall abzufangen, und das Ganze so lange zu probieren, bis die Datei wieder freigegeben ist. Damit das Ganze nicht in einer Endlosschleife endet, habe ich die Anzahl der Versuche allerdings auf 10 beschränkt:
context.Response.ContentType = contenttype;
context.Response.AddHeader("content-disposition", "attachment; filename=" + filename);
byte[] getContent = null;
bool loadFile = true;
if (!File.Exists(filepath))
throw new FileNotFoundException("Die Datei " + filepath + " existiert nicht.");
int exceptionCount = 0;
while (loadFile)
{
try
{
using (FileStream sourceFile = new FileStream(filepath, FileMode.Open))
{
long FileSize;
FileSize = sourceFile.Length;
getContent = new byte[(int) FileSize];
sourceFile.Read(getContent, 0, (int) sourceFile.Length);
loadFile = false;
}
}
catch(IOException exc)
{
if(exceptionCount < 10)
{
exceptionCount++;
System.Threading.Thread.Sleep(1000);
}
else
{
throw new IOException("Der Anhang kann auch nach 10 Versuchen nicht geöffnet werden", exc);
}
}
}
context.Response.BinaryWrite(getContent);
context.Response.End();
That's it.