2010-05-13 7 views
13

Ho un controller che effettua una connessione a un URL per recuperare un file CSV.Groovy Grails, Come si esegue lo streaming o il buffer di un file di grandi dimensioni nella risposta di un controller?

Sono in grado di inviare il file nella risposta utilizzando il seguente codice, questo funziona correttamente.

def fileURL = "www.mysite.com/input.csv" 
    def thisUrl = new URL(fileURL); 
    def connection = thisUrl.openConnection(); 
    def output = connection.content.text; 

    response.setHeader "Content-disposition", "attachment; 
    filename=${'output.csv'}" 
    response.contentType = 'text/csv' 
    response.outputStream << output 
    response.outputStream.flush() 

Tuttavia, ritengo che questo metodo non sia appropriato per un file di grandi dimensioni, poiché l'intero file viene caricato nella memoria del controller.

Desidero essere in grado di leggere il file di blocco per pezzo e di scrivere il file nel blocco di risposta per blocco.

Qualche idea?

risposta

23

Groovy OutputStreams può utilizzare InputStreams direttamente con l'operatore <<. OutputStream estrarrà automaticamente i dati con un buffer di dimensioni appropriate.

Quanto segue dovrebbe copiare in modo efficiente i dati, anche se il CSV è piuttosto grande.

def fileURL = "www.mysite.com/input.csv" 
def thisUrl = new URL(fileURL); 
def connection = thisUrl.openConnection(); 
def cvsInputStream = connection.inputStream 

response.setHeader "Content-disposition", "attachment; 
filename=${'output.csv'}" 
response.contentType = 'text/csv' 
response.outputStream << csvInputStream 
response.outputStream.flush() 
+3

Buona soluzione, ma ricordarsi di chiudere anche lo stream di input. Un'alternativa sicura è usare connection.withInputStream {...} – stenix