2010-05-13 23 views
13

J'ai un contrôleur qui établit une connexion à une URL pour récupérer un fichier CSV.Groovy Grails, Comment pouvez-vous streamer ou tamponner un gros fichier dans la réponse d'un contrôleur?

Je peux envoyer le fichier dans la réponse en utilisant le code suivant, cela fonctionne très bien.

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() 

Cependant, je pense que cette méthode est inappropriée pour un fichier volumineux, car le fichier entier est chargé dans la mémoire des contrôleurs. Je veux être capable de lire le morceau de fichier par morceau et écrire le morceau dans le morceau de réponse par morceau.

Des idées?

Répondre

23

Groovy OutputStreams peut prendre InputStreams directement avec l'opérateur <<. Le OutputStream tirera les données automatiquement avec un tampon de taille appropriée.

Les éléments suivants doivent copier efficacement les données, même si le fichier CSV est assez volumineux.

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

Bonne solution, mais n'oubliez pas de fermer également inputStream. Une alternative sûre consiste à utiliser connection.withInputStream {...} – stenix