zl程序教程

您现在的位置是:首页 >  后端

当前栏目

java实现服务器文件打包zip并下载的示例(边打包边下载)

2023-06-13 09:15:24 时间

使用该方法,可以即时打包文件,一边打包一边传输,不使用任何的缓存,让用户零等待!

复制代码代码如下:


/**
 *
 *mySocket客户端Socket
 *@paramfile待打包的文件夹或文件
 *@paramfileName打包下载的文件名
 *@throwsIOException
 */

privatevoiddown(Filefile,StringfileName)throwsIOException{
 OutputStreamoutputStream=mySocket.getOutputStream();
 StringBuffersb=newStringBuffer("HTTP/1.1200OK\r\n");
 sb.append("Server:java/1.1\r\n");
 sb.append("Content-Type:application/octet-stream;charset=UTF-8\r\n");
 //sb.append("User-Agent:Mozilla/4.0(compatible;MSIE6.0;WindowsNT5.0)\r\n");
 sb.append("Content-Disposition:attachment;filename="+fileName
   +"\r\n");
 sb.append("Transfer-Encoding:chunked\r\n");
 sb.append("Connection:Keep-Alive\r\n\r\n");
 outputStream.write(sb.toString().getBytes());
 outputStream.flush();
 ZipCompressorzipCompressor=newZipCompressor(newMyOutputStream(
   outputStream));
 zipCompressor.compress(file);
 System.out.println("zipend");  
 System.out.println("write"0\\r\\n\\r\\n"");
 outputStream.write("0\r\n\r\n".getBytes());//Transfer-Encoding:chunked传输结束标记
 outputStream.flush();
 outputStream.close();
 System.out.println("downloadstop");
 try{
  mySocket.close();
 }catch(Throwablet){
 }
}

复制代码代码如下:


packagecn.liangjintang.webserver.zipFile;

importjava.io.BufferedInputStream;
importjava.io.File;
importjava.io.FileInputStream;
importjava.io.OutputStream;
importjava.lang.reflect.Field;
importjava.util.zip.CRC32;
importjava.util.zip.CheckedOutputStream;
importjava.util.zip.ZipEntry;
importjava.util.zip.ZipOutputStream;

publicclassZipCompressor{
 staticfinalintBUFFER=8192;
 privateOutputStreamoutputStream;
 publicZipCompressor(MyOutputStreamoutputStream){
  this.outputStream=outputStream;
 }
 publicvoidcompress(Filefile){
  if(!file.exists())
   thrownewRuntimeException(file.getAbsolutePath()+"不存在!");
  try{
   CheckedOutputStreamcos=newCheckedOutputStream(outputStream,
     newCRC32());
   ZipOutputStreamout=newZipOutputStream(cos);
   Stringbasedir="";
   compress(file,out,basedir);
   out.close();//必须关闭,这样才会写入zip的结束信息,否则zip文件不完整.若想继续写入,可重写outputStream.close()方法
  }catch(Exceptione){
   thrownewRuntimeException(e);
  }
 }

 privatevoidcompress(Filefile,ZipOutputStreamout,Stringbasedir){
  //判断是目录还是文件
  if(file.isDirectory()){
   System.out.println("压缩:"+basedir+file.getName());
   this.compressDirectory(file,out,basedir);
  }else{
   System.out.println("压缩:"+basedir+file.getName());
   this.compressFile(file,out,basedir);
  }
 }

 //压缩一个目录
 privatevoidcompressDirectory(Filedir,ZipOutputStreamout,Stringbasedir){
  if(!dir.exists())
   return;

  File[]files=dir.listFiles();
  for(inti=0;i<files.length;i++){
   /**递归*/
   compress(files[i],out,basedir+dir.getName()+"/");
  }
 }

 //压缩一个文件
 privatevoidcompressFile(Filefile,ZipOutputStreamout,Stringbasedir){
  if(!file.exists()){
   return;
  }
  try{
   BufferedInputStreambis=newBufferedInputStream(
     newFileInputStream(file));
   ZipEntryentry=newZipEntry(basedir+file.getName());
   out.putNextEntry(entry);
   intcount;
   bytedata[]=newbyte[BUFFER];
   while((count=bis.read(data,0,BUFFER))!=-1){
    out.write(data,0,count);
   }
   bis.close();
  }catch(Exceptione){
   thrownewRuntimeException(e);
  }
 }
}

复制代码代码如下:
packagecn.liangjintang.webserver.zipFile;

importjava.io.FilterOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;

publicclassMyOutputStreamextendsFilterOutputStream{
 publicMyOutputStream(OutputStreamout){
  super(out);
 }

 finalbyte[]oneBytes="1\r\n".getBytes();
 finalbyte[]rnBytes="\r\n".getBytes();

 publicvoidwrite(intb)throwsIOException{
  out.write(oneBytes);//字节数1+CRLF
  out.write(b);//数据实体
  out.write(rnBytes);//CRLF
 }

 publicvoidwrite(byte[]b)throwsIOException{
  out.write(Integer.toHexString(b.length).getBytes());//字节数,十六进制
  out.write(rnBytes);//CRLF
  out.write(b);//数据实体
  out.write(rnBytes);//CRLF
 }

 publicvoidwrite(byte[]b,intoff,intlen)throwsIOException{
  out.write(Integer.toHexString(len-off).getBytes());//字节数,十六进制
  out.write(rnBytes);//CRLF
  out.write(b,off,len);//数据实体
  out.write(rnBytes);//CRLF
 }

 /**
 *重写该方法,否则OutputStream会被关闭,其他的数据<br/>
 *(如Transfer-Encoding:chunked传输结束标记)就不能再继续写入了
 */
 publicvoidclose()throwsIOException{
 }
}