Загрузка большого файла в ColdFusion с использованием CFHTTP - PullRequest
6 голосов
/ 19 января 2011

Я пытаюсь загрузить большой (600 МБ) двоичный файл на сервер, используя CFHTTP в Coldfusion 8:

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

Работает нормально для небольших файлов (100 МБ), но для больших я получаю ошибку Server 500: «java.lang.OutOfMemoryError: Java heap space».

Файл загружается из папки Dropbox - поэтому единственный доступный вариант - использовать HTTP GET.

Кто-нибудь знает, как его скачать, чтобы он не убивал сервер или тайм-аут?

Ответы [ 2 ]

14 голосов
/ 19 января 2011

Вы можете сделать это, вызвав Java из кода CF.Буферизованные входные и выходные потоки предназначены для хранения кусков данных, а не целого, избегая ошибок OutOfMemory.

getByteArray() - это вспомогательный метод, потому что нет способа объявить что-то вроде byte buf[]=new byte[1024];в CF напрямую.

В этом примере измените переменные 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>
2 голосов
/ 19 января 2011

Проблема в том, что он слишком большой.ColdFusion считывает всю информацию в память перед записью на диск.

Вам будет лучше использовать другой метод для получения файла.wget может выполнять http-запросы из командной строки.Что при разумном использовании CFEXECUTE, вероятно, это хороший путь.

...