6

Coldfusion 8でCFHTTPを使用して、大きな(600MB)バイナリファイルをサーバーにダウンロードしようとしています。

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

小さいファイル(100〜100 MB)の場合は正常に機能しますが、大きいファイルの場合は、「java.lang.OutOfMemoryError:Javaヒープスペース」というServer500エラーが発生します。

ファイルはDropboxフォルダーからダウンロードされているため、使用可能なオプションはHTTPGETを使用することだけです。

誰かがそれをダウンロードする方法を知っているので、それはサーバーを殺したりタイムアウトしたりしませんか?

4

2 に答える 2

14

これを行うには、CFコードからJavaを呼び出します。バッファリングされた入力および出力ストリームの分類対象は、OutOfMemoryエラーを回避するために、全体ではなくデータのチャンクを保持するように設計されています。

getByteArray()byte buf[]=new byte[1024];CFのように直接宣言する方法がないため、はヘルパーメソッドです。

この例では、sourcedestination変数を変更します。

<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>
于 2011-01-19T19:26:43.920 に答える
2

問題は、それが大きすぎることです。ColdFusionは、ディスクに書き込む前にすべてをメモリに読み込みます。

他の方法を使用してファイルを取得することをお勧めします。wgetはコマンドラインからhttpリクエストを実行できます。CFEXECUTEを慎重に使用することは、おそらく良い方法です。

于 2011-01-19T18:13:28.313 に答える