2011-01-19 37 views
6

Tôi đang cố gắng để tải về một lượng lớn (600MB) tập tin nhị phân để máy chủ sử dụng CFHTTP trên Coldfusion 8:Tải tập tin lớn trong ColdFusion sử dụng CFHTTP

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

Nó làm việc tốt cho các tập tin nhỏ hơn (100something MB) nhưng đối với người lớn, tôi nhận được lỗi máy chủ 500: "java.lang.OutOfMemoryError: Java heap space".

Tệp đang được tải xuống từ thư mục Dropbox - vì vậy chỉ có tùy chọn có sẵn là sử dụng HTTP GET.

Có ai có ý tưởng làm thế nào để tải xuống, vì vậy nó sẽ không giết máy chủ hoặc thời gian chờ?

+1

Nếu đó là một tập tin trong Dropbox, tại sao không chỉ cần cài đặt client Dropbox trên máy chủ, và xem các thư mục cho mới/file cập nhật? –

+0

Vì chúng tôi có vài khách hàng riêng biệt trên cùng một máy chủ - không thể cài đặt nhiều khách hàng Dropbox. Nhưng cảm ơn vì ý tưởng Ben. – Lucas

Trả lời

14

Bạn có thể thực hiện việc này bằng cách gọi Java từ mã CF. Các đầu vào dòng đầu vào và đầu ra được đệm được thiết kế để giữ các khối dữ liệu, thay vì toàn bộ điều, tránh các lỗi OutOfMemory.

getByteArray() là một phương thức trợ giúp vì không có cách nào để khai báo trực tiếp điều gì đó như byte buf[]=new byte[1024]; trong CF.

Trong ví dụ, hãy thay đổi các biến số sourcedestination.

Ví dụ

<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

Cách làm đẹp, đặc biệt đối với những người không có nền Java (như tôi). – Sergii

+0

Java rất tuyệt vời để biết với CF vì nó cho phép bạn làm việc xung quanh một số vấn đề với chức năng tích hợp sẵn. – orangepips

+0

Cảm ơn bạn rất nhiều orangepips, tôi sẽ thử. – Lucas

2

Vấn đề là nó quá lớn. ColdFusion đọc toàn bộ điều đó vào bộ nhớ trước khi ghi nó vào đĩa.

Bạn nên sử dụng một số phương pháp khác để tải tệp. wget có thể thực hiện các yêu cầu http từ một dòng lệnh. Điều đó với việc sử dụng CFEXECUTE một cách thận trọng có lẽ là một cách tốt để đi.

+0

Cảm ơn ý tưởng Al. – Lucas

Các vấn đề liên quan