2010-04-02 15 views
23

Sto facendo test con ASP.NET HttpHandler per scaricare un file che scrive direttamente sul flusso di risposta e non sono abbastanza sicuro sul modo in cui lo sto facendo. Questo è un metodo di esempio, in futuro, il file potrebbe essere memorizzato in un BLOB nel database:Alcune domande sulla scrittura sul flusso di risposta ASP.NET

 public void GetFile(HttpResponse response) 
    { 
     String fileName = "example.iso"; 
     response.ClearHeaders(); 
     response.ClearContent(); 
     response.ContentType = "application/octet-stream"; 
     response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName); 
     using (FileStream fs = new FileStream(Path.Combine(HttpContext.Current.Server.MapPath("~/App_Data"), fileName), FileMode.Open)) 
     { 
      Byte[] buffer = new Byte[4096]; 
      Int32 readed = 0; 

      while ((readed = fs.Read(buffer, 0, buffer.Length)) > 0) 
      { 
       response.OutputStream.Write(buffer, 0, readed); 
       response.Flush(); 
      } 
     } 
    } 

Ma, io non sono sicuro se questo è corretto o c'è un modo migliore per farlo. Le mie domande sono:

  1. Quando apro l'url con il browser, viene visualizzata la "Salva file" finestra ... ma sembra che il server ha iniziato già a spingere i dati nel flusso prima che faccio clic su "Salva ", è normale?
  2. Se rimuovo la riga "response.Flush()", quando apro l'url con il browser, ... vedo come il server web sta spingendo i dati ma la finestra di dialogo "Salva file" non viene visualizzata, (o almeno non in un tempo ragionevole) perché?
  3. Quando apro l'url con un oggetto WebRequest, vedo che HttpResponse.ContentLength è "-1", sebbene io possa leggere lo stream e ottenere il file. Qual è il significato di -1? Quando HttpResponse.ContentLength mostrerà la lunghezza della risposta? Ad esempio, ho un metodo che recupera un grande xml compresso con deflate come flusso binario, ma in quel caso ... quando accedo ad una WebRequest, in HttpResponse posso effettivamente vedere ContentLength con la lunghezza del flusso , perché?
  4. Qual è la lunghezza ottimale per l'array Byte [] che utilizzo come buffer per prestazioni ottimali in un server Web? Ho letto che è tra 4K e 8K ... ma quali fattori dovrei prendere in considerazione per prendere la decisione giusta.
  5. Questo metodo gonfia l'utilizzo della memoria di IIS o del client? o è in realtà il buffering del transfert correttamente?

Ci scusiamo per così tante domande, io sono abbastanza nuovo in sviluppo web: P

Cin cin.

+1

Si dovrebbe anche dare un'occhiata alle implementazioni di HttpHandler di Boilerplate qui (http://haacked.com/archive/2005/03/17/AnAbstractBoilerplateHttpHandler.aspx) e qui (http://www.hanselman.com /blog/PermaLink,guid,5c59d662-b250-4eb2-96e4-f274295bd52e.aspx). – R0MANARMY

+0

Il tuo modo di apprendere è apprezzato. Continua così . –

+0

Ciò funzionerà: [http://stackoverflow.com/questions/3362849/outofmemoryexception-when-send-big-file-500mb-using-filestream-aspnet][1] [ 1]: http://stackoverflow.com/questions/3362849/outofmemoryexception-when-send-big-file-500mb-using-filestream-aspnet –

risposta

16
  1. Sì; E 'normale.
  2. Se non si svuota mai, il browser non riceve alcuna risposta fino a quando non termina lo serever (nemmeno l'intestazione Content-Disposition). Pertanto, non sa di mostrare una finestra di dialogo.
  3. L'intestazione Content-Length viene impostata solo se l'intera risposta è memorizzata nel buffer (se non si scarica mai) o se si imposta da sé. In questo caso, puoi e devi impostare tu stesso; scrivere

    response.AppendHeader("Content-Length", new FileInfo(path).Length.ToString()); 
    
  4. Raccomando 4K; Non ho una base solida per la raccomandazione.
  5. Questo metodo è il modo migliore per farlo. Chiamando Flush all'interno del ciclo, si invia immediatamente la risposta lungo il cavo, senza alcun buffering. Tuttavia, per prestazioni aggiuntive, puoi utilizzare la compressione GZIP.
+0

Grazie a tutti, avete chiarito tutti i miei dubbi. Sono felice di essere entrato in questa comunità: D – vtortola

2
  1. Sì, è il buffering.
  2. Flush spinge il contenuto memorizzato nella cache nel browser. Se non viene mai premuto, non si otterrà una finestra di dialogo di salvataggio.
  3. Difficile da dire senza vedere i file/URL/flussi esatti che si stanno utilizzando.
  4. Penso che i fattori dipendano da quanto sia lenta la tua pagina, davvero. Avrai prestazioni migliori verso 4k. E forse, il valore più basso sarà migliore per ospitare connessioni più lente.
  5. Vedi # 1 & 2.
+0

Grazie a tutti, chiarite tutti i miei dubbi. Sono contento di essermi iscritto a questa community: D – vtortola

2

Per 3 # è necessario impostare l'intestazione Content-Length nella tua http-risposta. Molti di questi valori provengono da intestazioni http.

Credo che è possibile modificare il buffer modificando una proprietà di buffering sull'oggetto risposta su false. Non lo faccio da un po ', quindi non ricordo cosa potrebbe essere.

+0

Grazie a tutti, avete chiarito tutti i miei dubbi. Sono contento di essermi iscritto a questa community: D – vtortola

Problemi correlati