1

「ローカルビルド」で、一時フォルダーを作成し、その中に画像ファイルを追加して、ユーザーが圧縮してダウンロードすることに成功しました。残念ながら、テストサーバーにデプロイした後、そのような一時フォルダーを作成できず、許可エラーが原因で圧縮およびストリーミングできないと思います。基本的に私はパスにいます。Test-Server にフォルダーを作成するためのアクセス権を取得できず、このフォルダーとファイルを S3 バケットに保存してから、ここから zipOutputStream を作成する必要があります。 zipの作成を完了する前に、zipコンテンツを「オンザフライ」で応答に送信するだけです。これは可能ですか?もしそうなら、どうやってそうするつもりですか?この方法には、S3 にファイルを一時的に保存して圧縮してストリーミングするよりも利点があります。

フォルダーの作成と圧縮とストリーミングの現在のコード

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()
    }
}
4

1 に答える 1

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()
}
于 2013-08-29T08:26:25.833 に答える