2013-08-28 54 views
1

我已成功在我的「本地構建」中創建了臨時文件夾,並在其中添加了要由用戶壓縮和下載的圖像文件。不幸的是,在部署到我的測試服務器後,由於權限錯誤,我無法創建這樣的臨時文件夾,因此無法壓縮和傳輸它,我相信。基本上我在通過。我無法訪問在我的測試服務器上創建文件夾,並且需要將此文件夾和文件存儲在我的S3存儲桶中,然後從這裏創建一個zipOutputStream - 或者 - 如果可能的話,我認爲這可能是更好的解決方案,就是在我完成壓縮文件創建之前,將「郵件內容」發送到響應中。這可能嗎?如果是的話,怎麼會這樣做呢?這種方法是否有利於通過將文件臨時存儲在S3上進行壓縮和流式傳輸。在完成zip創建之前發送zip內容至響應

現行規範創建文件夾和壓縮和流

def downloadZip(){ 

    def fName = params.fName // ZipFile Name passed in 'example.zip' 
    def fLoc = params.fLoc //Folder Location passed in '/example' 
    def user = User.get(fLoc as Long) //Get the Users files to be zipped    
    def urlList = [] 
    List ownedIds 

    //Create a temporary directory to place files inside before zipping 
    new File(fLoc).mkdir() 

    //Dynamic Resource 'http://example.com/' -or- 'http://localhost:8080/' 
    def location = "${resource(dir:'/', absolute:true)}" 
    //Collect and Download QR-Codes image files 
    ownedIds = user.geolinks.collect { 
     //Define Url for Download 
     def urls = (location+"qrCode/download?u=http%3A%2F%2Fqr.ageoa.com%2F" +it.linkAddress+ "&s=150&n=" +it.linkAddress)   
     //Download each QR-Code 
     download2(urls,fLoc) 
    } 

    //ZIP the directory that was created and filled with the QR codes 
    String zipFileName = fName 
    String inputDir = fLoc 

    ZipOutputStream zipFile = new ZipOutputStream(new FileOutputStream(zipFileName)) 
    new File(inputDir).eachFile() { file -> 
     zipFile.putNextEntry(new ZipEntry(file.getName())) 
     def buffer = new byte[1024] 
     file.withInputStream { i -> 
      def l = i.read(buffer) 
      // check whether the file is empty 
      if (l > 0) { 
       zipFile.write(buffer, 0, l) 
      } 
     } 
     zipFile.closeEntry() 
    } 
    zipFile.close() 

    //Download QR-Code Zip-File 
    try { 
     def file = new File(fName)  
     response.setContentType("application/octet-stream") 
     response.setHeader("Content-disposition", "attachment;filename=${file.getName()}") 
     response.outputStream << file.newInputStream() // Performing a binary stream copy       
    }  
    catch(Exception e){ 
      e.printStackTrace() 
    } 

    //Delete Temporary Folder 
    def dir2 = new File(fLoc) 
    dir2.deleteDir() 
} 

//Download All QR-Codes images to folder [userID] 
def download2(address, dir){ 
    def file = new FileOutputStream(dir+"/"+address.tokenize("&n=")[-1]+".png") 
    if(file){ 
     def out = new BufferedOutputStream(file) 
     out << new URL(address).openStream() 
     out.close() 
    } 
} 
+1

難道你不能只是做'ZipOutputStream zipFile = new ZipOutputStream(response.outputStream)'然後做你做的很多? –

+0

感謝Tim的提示,但是如果我無法將圖像文件放置在服務器上,並且我正在創建/下載,那麼如何加載zipOutputStream和我的內容?我怎麼能填充這個zip文件與我的內容在一個流中我想我也是這樣問的?難道我在zipFile.putNextEntry()中以某種方式構建它嗎?你是否在某個地方有過這樣的例子,或者我有足夠的代碼來切割和操作?順便說一句,謝謝你的提示。 –

+0

添加了一個答案,這是我的意思的工作示例...希望它有幫助! –

回答

2

對,這應該這樣做,讓我知道,如果它的任何沒有意義......

// A list of things to download and add to the zip 
List<URL> testList = [ 'http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=6', 
         'https://www.google.co.uk/images/srpr/logo4w.png' ]*.toURL() 
response.setHeader("Content-disposition", "attachment; filename=resources.zip") 
response.contentType = "application/octet-stream" 

// Wrap the response stream in a zipoutputstream 
new ZipOutputStream(response.outputStream).withStream { zos -> 

    // Always add a root folder to zip files, not to do so is spiteful 
    zos.putNextEntry(new ZipEntry("resources/")) 

    // For each URL 
    testList.each { res -> 

     // Get a name for this file in the zip 

     // This bit might be the tricky bit as I guess you don't know the file 
     // names. So instead of this you might need to check the response 
     // object from opening a connection to the URL. However, without a 
     // working example URL from you, I can't be sure :-(
     String name = res.path.split('/')[ -1 ] 

     // Create a zip entry for it 
     zos.putNextEntry(new ZipEntry("resources/$name")) 

     // Write the resource stream into our zip 
     res.withInputStream { ins -> 
      zos << ins 
     } 

     // Close this resource 
     zos.closeEntry() 
    } 
    // Close the root folder 
    zos.closeEntry() 
} 
+0

謝謝你的例子。我能夠從我想要的圖像中創建一個urls數組,並用.tokenize()命名它們,並將它們填充到zip流中。 :) –