java实现服务器文件打包zip并下载的示例(边打包边下载)
使用该方法,可以即时打包文件,一边打包一边传输,不使用任何的缓存,让用户零等待!
/**
*
*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);
}
}
}
importjava.io.FilterOutputStream; publicclassMyOutputStreamextendsFilterOutputStream{ finalbyte[]oneBytes="1\r\n".getBytes(); publicvoidwrite(intb)throwsIOException{ publicvoidwrite(byte[]b)throwsIOException{ publicvoidwrite(byte[]b,intoff,intlen)throwsIOException{ /**
packagecn.liangjintang.webserver.zipFile;
importjava.io.IOException;
importjava.io.OutputStream;
publicMyOutputStream(OutputStreamout){
super(out);
}
finalbyte[]rnBytes="\r\n".getBytes();
out.write(oneBytes);//字节数1+CRLF
out.write(b);//数据实体
out.write(rnBytes);//CRLF
}
out.write(Integer.toHexString(b.length).getBytes());//字节数,十六进制
out.write(rnBytes);//CRLF
out.write(b);//数据实体
out.write(rnBytes);//CRLF
}
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{
}
}相关文章