grails - Send the zip content to response before you complete the zip creation -
i have successfully, on "local-build", been able create temp-folder , add image files inside of zipped , downloaded user. unfortunately after deploying test-server, unable create such temp folder , thusly cannot zip , stream it, believe, due permission errors. @ pass. cannot gain access create folders on test-server, , either need store folder , files on s3 bucket , create zipoutputstream here -or- think may better solution if possible, "on-the-fly" send zip content response before complete zip creation. possible? , if how go doing so? there benefit method on storing files temporarily on s3 zipped , streamed.
current code folder creation , zipping , streaming
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 long ) //get users files zipped def urllist = [] list ownedids //create temporary directory 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 , download qr-codes image files ownedids = user.geolinks.collect { //define url 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 directory created , filled 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 { -> def l = i.read(buffer) // check whether file 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 binary stream copy } catch(exception e){ e.printstacktrace() } //delete temporary folder def dir2 = new file(floc) dir2.deletedir() } //download qr-codes images 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() } }
right, should it, let me know if of doesn't make sense...
// list of things download , add 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 response stream in zipoutputstream new zipoutputstream( response.outputstream ).withstream { zos -> // add root folder zip files, not spiteful zos.putnextentry( new zipentry( "resources/" ) ) // each url testlist.each { res -> // name file in zip // bit might tricky bit guess don't know file // names. instead of might need check response // object opening connection url. however, without // working example url you, can't sure :-( string name = res.path.split( '/' )[ -1 ] // create zip entry zos.putnextentry( new zipentry( "resources/$name" ) ) // write resource stream our zip res.withinputstream { ins -> zos << ins } // close resource zos.closeentry() } // close root folder zos.closeentry() }
Comments
Post a Comment