我正在尝试使用Coldfusion 8上的CFHTTP将大型(600MB)二进制文件下载到服务器:
<cfhttp
method="get"
url="#fileURL#"
path="#filePath#"
file="#fileName#"
timeout="600"
getasbinary="auto"
>
它适用于较小的文件(100something MB)但是对于较大的文件我收到Server 500错误:“java.lang.OutOfMemoryError:Java堆空间”。
正在从Dropbox文件夹下载文件 - 因此只有可用选项才能使用HTTP GET。
有没有人知道如何下载它,所以它不会杀死服务器或超时?
答案 0 :(得分:14)
您可以通过从CF代码调用Java来完成此操作。缓冲的输入和输出流classees旨在保留数据块而不是整个数据,从而避免OutOfMemory错误。
getByteArray()
是一种辅助方法,因为无法直接在CF中声明类似byte buf[]=new byte[1024];
的内容。
在示例中更改source
和destination
变量。
示例
<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>
答案 1 :(得分:2)
问题是它太大了。 ColdFusion在将其写入磁盘之前将整个内容读入内存。
使用其他方法获取文件会更好。 wget可以从命令行执行http请求。明智地使用CFEXECUTE可能是一个很好的方法。