aawwmate
2010-07-29 15:11
浏览 434
已采纳

关于jsp打包zip文件下载的问题,请帮忙解决。

我现在需要在项目中实现对多个文件打包成zip下载。从网上找到一段代码如下,可用,但是,会提示getOutputStream已经被called的异常。不知道哪里的问题,请帮忙解决。
另外这个代码是先保存为文件,然后再向reaponse输出流的,有没有直接压缩后就输出不保存本地文件的方法,请指教。
另外,如果能够实现一次压缩多个文件夹就更好了。
还有,zip文件是不是可以附带文本性的注释的呢?
[code="java"]
package com.xinkao.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.tools.zip.*;
import javax.servlet.http.HttpServletResponse;

public class JspFileDownload {
/** request object */
private HttpServletResponse response = null;

/** file type: -1 un-setting; 0 normal file; 1 zip file ;2 stream*/
private int fileType = -1;

/** file name to be displayed */
private String disFileName = null;

/** zip file path */
private String zipFilePath = null;

/** file to be zipped */
private String[] zipFileNames = null;

private boolean zipDelFlag = false;

/** file to be downloaded */
private String downFileName = null;

/** error code 0 */
private static final int PROCESS_OK = 0;

/** error code 1 */
private static final int RESPONSE_IS_NULL = 1;

/** error code 2 */
private static final int UNSET_DOWNLOADTYPE = 2;

/** error code 3 */
private static final int UNSET_DIS_FILE_NAME = 3;

/** error code 4 */
private static final int UNSET_DOWN_FILE_NAME = 4;

/** error code 9 */
private static final int IO_EXCEPTION = 9;

/**
 * set response object
 * @param response response Object
 */
public void setResponse(HttpServletResponse response){
    this.response = response;
}

/**
 * set file type 0 normal file; 1 zip file ;2 stream
 * @param fileType
 */
public void setDownType(int fileType){
    this.fileType = fileType;
}

/**
 * set display file name
 * @param fileName
 */
public void setDisFileName(String fileName){
    this.disFileName = fileName;
}

/**
 * set zip file path
 * @param fileNames
 */
public void setZipFilePath( String path ){
    this.zipFilePath = path;
}

public void setZipDelFlag(boolean b){
    this.zipDelFlag = b;
}

/**
 * set zip file names
 * @param fileNames
 */
public void setZipFileNames(String[] fileNames){
    this.zipFileNames = fileNames;
}

/**
 * set download file name
 * @param fileName
 */
public void setDownFileName(String fileName){
    this.downFileName = fileName;
}

/**
 * set file content
 * @param fileContent
 */
public int setFileContent(String fileContent){  
    try{    
        byte[] buffs = fileContent.getBytes("GBK");
        response.getOutputStream().write(buffs);
    }catch(IOException e){
        return IO_EXCEPTION;
    }
    return PROCESS_OK;
}

/**
 * set file content
 * @param fileContent
 */
public int setFileContent(byte[] fileContent){
    try{
        response.getOutputStream().write(fileContent);
    }catch(IOException e){
        return IO_EXCEPTION;
    }
    return PROCESS_OK;
}

/**
 * set file content end
 *
 */
public int setFileContentEnd(){
    try{
        response.getOutputStream().close();
    }catch(IOException e){
        return IO_EXCEPTION;
    }
    return PROCESS_OK;
}

/**
 * main process
 * @return
 */
public int process(){
    int status = PROCESS_OK;

    status = preCheck();
    if ( status != PROCESS_OK )
        return status;

    String fileName = disFileName;

    response.setContentType("APPLICATION/OCTET-STREAM");   
    response.setHeader("Content-Disposition","attachment;filename=\"" + fileName + "\"");
    int BUFSIZE = 1024 * 8;     
    int rtnPos = 0;
    byte[] buffs = new byte[ BUFSIZE ];
    FileInputStream inStream = null;
    ZipOutputStream zos = null;
    InputStream is = null;
    String filepath = null;
    try{

        if ( fileType == 0 || fileType == 1){
            if ( fileType == 0 ){
                filepath = downFileName;   
            }else{
                filepath = zipFilePath + fileName;
                String[] fileToZip = zipFileNames;          
                zos=new ZipOutputStream(new FileOutputStream(filepath));
                ZipEntry ze=null;
                byte[] buf=new byte[BUFSIZE];
                int readLen=0;
                for (int i= 0;i<fileToZip.length;i++){
                    File f= new File(fileToZip[i]);

                    ze=new ZipEntry(f.getName());
                    ze.setSize(f.length());
                    ze.setTime(f.lastModified());

                    zos.putNextEntry(ze);
                    is=new BufferedInputStream(new FileInputStream(f));
                    while ((readLen=is.read(buf, 0, BUFSIZE))!=-1) {
                        zos.write(buf, 0, readLen);
                    }
                    is.close();
                }
                zos.close();
            }

            inStream =new FileInputStream(filepath);   
            while((rtnPos=inStream.read(buffs)) >0)   
                response.getOutputStream().write(buffs,0,rtnPos);   
            response.getOutputStream().close();   
            inStream.close();
        }
        if ( zipDelFlag ){
            File fToDel = new File(filepath);
            fToDel.delete();
        }

    }catch(IOException e){
        return IO_EXCEPTION;
    }finally{
        try{
            if ( inStream != null ){
                inStream.close();
                inStream = null;
            }
            if ( zos != null ){
                zos.close();
                zos = null;
            }
            if ( is != null ){
                is.close();
                is = null;
            }
        }catch (IOException e){
        }
    }
    return status;
}

/**
 * pre check.
 * @return
 */
private int preCheck(){
    if ( response == null )
        return RESPONSE_IS_NULL;

    if ( disFileName == null || disFileName.trim().length() == 0 )
        return UNSET_DIS_FILE_NAME;
    if ( fileType == -1 )
        return UNSET_DOWNLOADTYPE;
    else if ( fileType == 0 ){
        if ( downFileName == null || downFileName.trim().length() == 0 )
            return UNSET_DOWN_FILE_NAME;
        else{
            if ( !isFile( downFileName ) )
                return UNSET_DOWN_FILE_NAME;
        }

    }else if ( fileType == 1 ){
        if ( zipFilePath == null || zipFilePath.length() == 0 )
            return UNSET_DOWN_FILE_NAME;
        else{
            if ( !isDirect(zipFilePath) )
                return UNSET_DOWN_FILE_NAME;
        }
        if ( zipFileNames == null || zipFileNames.length == 0 )
            return UNSET_DOWN_FILE_NAME;
        else{
            for ( int i=0;i<zipFileNames.length;i++ ){
                if ( zipFileNames[i] == null || zipFileNames[i].trim().length() == 0 )
                    return UNSET_DOWN_FILE_NAME;
                else{
                    if ( !isFile( zipFileNames[i] ) )
                        return UNSET_DOWN_FILE_NAME;
                }
            }
        }
    }else if ( fileType == 2 ){
        //doing nothing
    }else{
        return UNSET_DOWNLOADTYPE;
    }
    return PROCESS_OK;
}

private boolean isFile(String fileName){
    File f = new File(fileName);
    if (!f.exists() || !f.isFile())
        return false;
    return true;
}

private boolean isDirect(String filePath){
    File f = new File(filePath);
    if (!f.exists() || !f.isDirectory())
        return false;
    return true;
}

}

[/code]

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • weixin_42525443 2010-07-30 14:24
    已采纳

    不好意思,还有一个问题没有看到,

    zos=new ZipOutputStream(new FileOutputStream(filepath));
    改成
    zos=new ZipOutputStream(response.getOutputStream());

    然后把下面读文件输出部分的删除掉,就可以实现不写文件直接输出.

    点赞 评论
  • iteye_5246 2010-07-29 18:25

    看看附件中的类吧专门处理zip的
    package com.emice.common2.util;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;

    import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipFile;
    import org.apache.tools.zip.ZipOutputStream;

    public class ZipUtil {

    private static void zip(
            ZipOutputStream out,
            File f,
            String base,
            boolean first) throws Exception {
        if (first) {
            if (f.isDirectory()) {
                out.putNextEntry(new ZipEntry("/"));
                base = base + f.getName();
                first = false;
            } else {
                base = f.getName();
            }
        }
        if (f.isDirectory()) {
            File[] fl = f.listFiles();
            if(!"".equals(base)){
                base = base + "/";
            }
    
            for (int i = 0; i < fl.length; i++) {
                zip(out, fl[i], base + fl[i].getName(), first);
            }
        } else {
            out.putNextEntry(new ZipEntry(base));
            FileInputStream in = null;
            try{
                in = new FileInputStream(f);
                IOUtil.write(out, in, 1024*1024);
            }finally{
                IOUtil.close(in);
            }
        }
    }
    /*
     * 解压文件
     * unZip为解压路径1�7
     */
    
    private static void unZip(
            ZipFile zipFile,
            File unZipRoot) throws Exception, IOException {
        java.util.Enumeration e = zipFile.getEntries();
        while (e.hasMoreElements()) {
            ZipEntry zipEntry = (ZipEntry) e.nextElement();
            if (zipEntry.isDirectory()) {
                continue;
            }
            InputStream fis = null;
            FileOutputStream fos = null;
            try{
                fis = zipFile.getInputStream(zipEntry);
                File file = new File(unZipRoot,zipEntry.getName());
                File parentFile = file.getParentFile();
                parentFile.mkdirs();
                fos = new FileOutputStream(file);
                IOUtil.write(fos, fis, 1024*1024);
            }finally{
                IOUtil.close(fis);
                IOUtil.close(fos);
            }
    
        }
    }
    
    public static void zip(File zipFileName, File inputFileOrFolderName) throws Exception {
        ZipOutputStream out = null;
        try{
            out = new ZipOutputStream(new FileOutputStream(zipFileName));
            out.setEncoding("gbk");
            zip(out, inputFileOrFolderName, "", true);
        }catch(Exception exp){
            throw exp;
        }finally{
            IOUtil.close(out);
        }
    }
    
    public static void zip(File zipFileName, File inputFileOrFolderName, boolean first) throws Exception {
        ZipOutputStream out = null;
        try{
            out = new ZipOutputStream(new FileOutputStream(zipFileName));
            out.setEncoding("gbk");
            zip(out, inputFileOrFolderName, "", first);
        }catch(Exception exp){
            throw exp;
        }finally{
            IOUtil.close(out);
        }
    }
    
    public static void unZip(File zipFile, File unZipFolder) throws Exception {
        ZipFile zf = new ZipFile(zipFile, "gbk");
        unZip(zf, unZipFolder);
    }
    

    // public static void zipFiles(List srcfile, File zipfile) {
    // byte[] buf = new byte[1024];
    // try {
    // // Create the ZIP file
    // ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipfile));
    // // Compress the files
    // for (File file : srcfile) {
    // FileInputStream in = new FileInputStream(file);
    // // Add ZIP entry to output stream.
    // out.putNextEntry(new ZipEntry(file.getName()));
    // // Transfer bytes from the file to the ZIP file
    // int len;
    // while ( (len = in.read(buf)) > 0) {
    // out.write(buf, 0, len);
    // }
    // // Complete the entry
    // out.closeEntry();
    // in.close();
    // }
    // // Complete the ZIP file
    // out.close();
    // System.out.println("压缩完成.");
    // }
    // catch (IOException e) {
    // e.printStackTrace();
    // }
    // }

    public static void main(String[] args) throws Exception {
        zip(new File("E:/test/test", "head.zip"), new File("E:/test/test/新建文件夹"), false);
    

    // unZip(new File("E:/test/test/head.zip"), new File("E:/test/test/head"));
    String encode = System.getProperty("file.encoding");
    System.out.println("encode --------- "+encode);

    }
    

    }

    点赞 评论
  • weixin_42525443 2010-07-30 14:19

    你好,jsp里面有个标准对象叫做out,他会被tomcat默认创建,通过封装respose.getOutputStream()来实现,所以在jsp页面使用respose.getOutputStream()都会提示已经被调用过了.

    Zip是可以添加注释的ZipOutputStream里有个setComment方法,你调用一下就可以添加了。

    点赞 评论
  • iteye_3365 2010-08-02 17:11

    别用jsp,不小心有个空格回车啥的你就开始Output了,用servlet吧

    或者先写到文件上给链接

    点赞 评论

相关推荐 更多相似问题