Frage

Im Moment habe ich eine Download-Site für meine Schule, die in .net basiert. Wir bieten alles von Anti-Virus-, Autocad, spss, im Büro, und eine Reihe von großen Anwendungen für Studenten zum Download bereit. Es ist zur Zeit Setup sie in 1 von 2 Möglichkeiten, zu behandeln; etwas mehr als 800 MB wird direkt über eine separate Webseite zugreifbar während unter 800 MB hinter .net Code mit einem Filestream gesichert ist es dem Anwender in 10.000 Byte Chunks zu füttern. Ich habe alle möglichen Probleme mit Downloads auf diese Weise füttern ... Ich möchte in der Lage sein, die großen Downloads zu sichern, aber die .net-Website können nicht damit umgehen, und die kleineren Dateien werden oft fehlschlagen. Gibt es eine bessere Annäherung an das?

Bearbeiten - ich wollte nur aktualisieren, wie ich das endlich gelöst: Ich beendete mein Download-Verzeichnis als virtuelles Verzeichnis in iis und angegebenen benutzerdefinierten HTTP-Handler addieren. Der Handler packte den Dateinamen aus der Anforderung und überprüft Berechtigungen basierend auf, dass dann entweder umgeleitet, die Benutzer auf einen Fehler / Login-Seite, oder lassen Sie den Download fortsetzen. Ich habe mit dieser Lösung keine Probleme hat, und ich habe jetzt wahrscheinlich 7 Monate auf sie gewesen, Dateien mehrere Gigs in der Größe zu dienen.

War es hilfreich?

Lösung

Ich habe zwei Empfehlungen:

  • die Puffergröße erhöhen, so dass es weniger Iterationen

UND / ODER

  • Rufen Sie IsClientConnected nicht bei jeder Iteration.

Der Grund dafür ist, dass nach Microsoft-Richtlinien :

hat Response.IsClientConnected einige Kosten, so dass es nur vor einer Operation verwenden, die mindestens dauert, sagen 500 Millisekunden (das ist eine lange Zeit, wenn Sie einen Durchsatz von Dutzenden von Seiten pro Sekunde aufrecht zu erhalten sind versuchen). Als allgemeine Faustregel gilt: Sie es nicht in jeder Iteration einer engen Schleife rufen

Andere Tipps

Wenn Sie Performance-Probleme haben und Sie liefern Dateien, die auf dem Dateisystem vorhanden ist (im Vergleich zu einem DB), verwenden Sie die HttpResponse.TransmitFile Funktion.

Wie für die Fehler, haben Sie wahrscheinlich einen Fehler. Wenn Sie den Code schreiben können Sie bessere Antwort sein.

Schauen Sie in Bit Torrent. Es wurde entwickelt, die speziell für diese Art der Sache und ist sehr flexibel.

Was ist falsch mit einem robusten Web-Server (zB Apache) mit und lassen Sie es mit Dateien umgehen. So wie Sie jetzt größere Dateien auf einen Webserver trennen, warum dient nicht kleinere Dateien auf die gleiche Weise auch?

Gibt es einige versteckte Anforderungen dies zu verhindern?

Ok, das ist, was es sieht derzeit wie ...

    Stream iStream = null;

// Buffer to read 10K bytes in chunk:
byte[] buffer = new Byte[10000];

// Length of the file:
int length;

// Total bytes to read:
long dataToRead;

if (File.Exists(localfilename))
{
    try
    {
        // Open the file.
        iStream = new System.IO.FileStream(localfilename, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

        // Total bytes to read:
        dataToRead = iStream.Length;

        context.Response.Clear();
        context.Response.Buffer = false;
        context.Response.ContentType = "application/octet-stream";
        Int64 fileLength = iStream.Length;
        context.Response.AddHeader("Content-Length", fileLength.ToString());
        context.Response.AddHeader("Content-Disposition", "attachment; filename=" + originalFilename);

        // Read the bytes.
        while (dataToRead > 0)
        {
            // Verify that the client is connected.
            if (context.Response.IsClientConnected)
            {
                // Read the data in buffer.
                length = iStream.Read(buffer, 0, 10000);

                // Write the data to the current output stream.
                context.Response.OutputStream.Write(buffer, 0, length);

                // Flush the data to the HTML output.
                context.Response.Flush();

                buffer = new Byte[10000];
                dataToRead = dataToRead - length;
            }
            else
            {
                //prevent infinite loop if user disconnects
                dataToRead = -1;
            }
        }
        iStream.Close();
        iStream.Dispose();
    }
    catch (Exception ex)
    {
        if (iStream != null)
        {
            iStream.Close();
            iStream.Dispose();
        }
        if (ex.Message.Contains("The remote host closed the connection"))
        {
            context.Server.ClearError();
            context.Trace.Warn("GetFile", "The remote host closed the connection");
        }
        else
        {
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Error occurred");
            context.Trace.Warn("IHttpHandler", "DownloadFile: - Exception", ex);
        }
        context.Response.Redirect("default.aspx");
    }
}

Es gibt eine Menge von Lizenzbeschränkungen ... zum Beispiel haben wir eine Office 2007-Lizenzvereinbarung, die alle technischen Personal auf dem Campus sagt können Office herunterladen und installieren, aber nicht Studenten. Also lassen wir die Schüler nicht herunterladen. So war unsere Lösung diese Downloads hinter .net zu verstecken.

Amazon S3 klingt ideal für das, was man braucht, aber es ist von kommerziellen Service und fileas werden von ihren Servern bedient.

Sie sollten versuchen, amazon zu kontaktieren und für die akademischen Preis fragen. Auch wenn sie keinen haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top