2011-01-19 22 views
6

Estoy intentando descargar un gran tamaño (600 MB) archivo binario en el servidor mediante CFHTTP en ColdFusion 8:descarga de archivos de gran tamaño en ColdFusion utilizando CFHTTP

<cfhttp 
    method="get" 
    url="#fileURL#" 
    path="#filePath#" 
    file="#fileName#" 
    timeout="600" 
    getasbinary="auto" 
> 

Está funcionando muy bien para archivos más pequeños (100something MB), pero para el más grande, recibo el error Server 500: "java.lang.OutOfMemoryError: Java montón montón".

El archivo se está descargando desde una carpeta de Dropbox, por lo que la única opción disponible es utilizar HTTP GET.

¿Alguien tiene idea de cómo descargarlo, por lo que no mataría el servidor o el tiempo de espera?

+1

Si se trata de un archivo en Dropbox, por qué no sólo tiene que instalar el cliente de Dropbox en el servidor, y ver el directorio para los archivos nuevos/actualizados? –

+0

Porque tenemos un par de clientes separados en el mismo servidor: no se pueden instalar varios clientes de Dropbox. Pero gracias por la idea, Ben. – Lucas

Respuesta

14

Puede hacer esto llamando a Java desde el código CF. Los classees de flujo de entrada y salida almacenados en búfer están diseñados para contener fragmentos de datos, en lugar de todo, evitando errores de OutOfMemory.

getByteArray() es un método de ayuda porque no hay manera de declarar algo como byte buf[]=new byte[1024]; en CF directamente.

En el ejemplo, cambie las variables source y destination.

Ejemplo

<cfset source = 'protocol://domain/path/to/file.ext'> 
<cfset destination = getDirectoryFromPath(getCurrentTemplatePath()) & listlast(source, "/")> 
<cffunction name="getByteArray" access="private" returnType="binary" output="no"> 
    <cfargument name="size" type="numeric" required="true"/> 
    <cfset var emptyByteArray = 
     createObject("java", "java.io.ByteArrayOutputStream").init().toByteArray()/> 
    <cfset var byteClass = emptyByteArray.getClass().getComponentType()/> 
    <cfset var byteArray = 
     createObject("java","java.lang.reflect.Array").newInstance(byteClass, arguments.size)/> 
    <cfreturn byteArray/> 
</cffunction> 

<cfscript> 
uri = createObject("java", "java.net.URL").init(source); 
uis = uri.openStream(); 
bis = createObject("java", "java.io.BufferedInputStream").init(uis); 
fos = createObject("java", "java.io.FileOutputStream").init(destination); 
bos = createObject("java", "java.io.BufferedOutputStream").init(fos); 
buffer = getByteArray(1024); 
len = bis.read(buffer); 
while(len > 0) { 
    bos.write(buffer,0,len); 
    len = bis.read(buffer); 
} 
bos.close(); 
bis.close(); 
fos.close(); 
uis.close(); 
</cfscript> 
+0

Nice howto, especialmente para personas sin antecedentes Java (como yo). – Sergii

+0

Java es genial de conocer con CF porque le permite solucionar algunos de los problemas con la funcionalidad incorporada. – orangepips

+0

Muchas gracias orangepips, lo intentaré. – Lucas

2

El problema es que es demasiado grande. ColdFusion lee todo en la memoria antes de escribirlo en el disco.

Será mejor que utilice algún otro método para obtener el archivo. wget puede hacer solicitudes http desde una línea de comandos. Que con el uso juicioso de CFEXECUTE es probablemente una buena forma de hacerlo.

+0

Gracias por la idea Al. – Lucas

Cuestiones relacionadas