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

 更新时间:2014年04月13日 09:18:40   作者:  
这篇文章主要介绍了java实现服务器文件打包zip并下载的示例,使用该方法,可以即时打包文件,一边打包一边传输,不使用任何的缓存,让用户零等待,需要的朋友可以参考下

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

复制代码 代码如下:

/**
 *
 * mySocket 客户端 Socket
 * @param file 待打包的文件夹或文件
 * @param fileName 打包下载的文件名
 * @throws IOException
 */

private void down(File file, String fileName) throws IOException {
 OutputStream outputStream = mySocket.getOutputStream();
 StringBuffer sb = new StringBuffer("HTTP/1.1 200 OK\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;Windows NT 5.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();
 ZipCompressor zipCompressor = new ZipCompressor(new MyOutputStream(
   outputStream));
 zipCompressor.compress(file);
 System.out.println("zip end");  
 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("download stop");
 try {
  mySocket.close();
 } catch (Throwable t) {
 }
}

复制代码 代码如下:

package cn.liangjintang.webserver.zipFile;

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

public class ZipCompressor {
 static final int BUFFER = 8192;
 private OutputStream outputStream;
 public ZipCompressor(MyOutputStream outputStream) {
  this.outputStream=outputStream;
 }
 public void compress(File file) {
  if (!file.exists())
   throw new RuntimeException(file.getAbsolutePath() + "不存在!");
  try {
   CheckedOutputStream cos = new CheckedOutputStream(outputStream,
     new CRC32());
   ZipOutputStream out = new ZipOutputStream(cos);
   String basedir = "";
   compress(file, out, basedir);
   out.close();//必须关闭,这样才会写入zip的结束信息,否则zip文件不完整.若想继续写入,可重写outputStream.close()方法
  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }

 private void compress(File file, ZipOutputStream out, String basedir) {
  //判断是目录还是文件
  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);
  }
 }

 // 压缩一个目录
 private void compressDirectory(File dir, ZipOutputStream out, String basedir) {
  if (!dir.exists())
   return;

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

 //压缩一个文件
 private void compressFile(File file, ZipOutputStream out, String basedir) {
  if (!file.exists()) {
   return;
  }
  try {
   BufferedInputStream bis = new BufferedInputStream(
     new FileInputStream(file));
   ZipEntry entry = new ZipEntry(basedir + file.getName());
   out.putNextEntry(entry);
   int count;
   byte data[] = new byte[BUFFER];
   while ((count = bis.read(data, 0, BUFFER)) != -1) {
    out.write(data, 0, count);
   }
   bis.close();
  } catch (Exception e) {
   throw new RuntimeException(e);
  }
 }
}

复制代码 代码如下:

package cn.liangjintang.webserver.zipFile;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class MyOutputStream extends FilterOutputStream {
 public MyOutputStream(OutputStream out) {
  super(out);
 }

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

 public void write(int b) throws IOException {
  out.write(oneBytes);//字节数1+CRLF
  out.write(b);//数据实体
  out.write(rnBytes);//CRLF
 }

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

 public void write(byte[] b, int off, int len) throws IOException {
  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传输结束标记)就不能再继续写入了
  */
 public void close() throws IOException {
 }
}

相关文章

  • 详解Spring Data Jpa当属性为Null也更新的完美解决方案

    详解Spring Data Jpa当属性为Null也更新的完美解决方案

    这篇文章主要介绍了详解Spring Data Jpa当属性为Null也更新的完美解决方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • Java SMM框架关联关系映射示例讲解

    Java SMM框架关联关系映射示例讲解

    SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层,使用spring MVC负责请求的转发和视图管理,spring实现业务对象管理,mybatis作为数据对象的持久化引擎
    2022-08-08
  • Mybatis-plus批量去重插入ON DUPLICATE key update使用方式

    Mybatis-plus批量去重插入ON DUPLICATE key update使用方式

    这篇文章主要介绍了Mybatis-plus批量去重插入ON DUPLICATE key update使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-12-12
  • SpringBoot整合swagger的操作指南

    SpringBoot整合swagger的操作指南

    Swagger 是一个开源的框架,用于设计、构建、文档化和使用 RESTful 风格的 Web 服务,Spring Boot 是一个用于构建独立的、基于生产级别的 Spring 应用程序的框架,本文讲给大家介绍一下SpringBoot整合swagger的操作指南,需要的朋友可以参考下
    2023-09-09
  • Java线程中的线程本地变量ThreadLocal详解

    Java线程中的线程本地变量ThreadLocal详解

    这篇文章主要介绍了Java线程中的线程本地变量ThreadLocal详解,ThreadLocal存放的值是线程内共享的,线程间互斥的,主要用于线程内共享一些数据,避免通过参数来传递,这样处理后,能够优雅的解决一些实际问题,需要的朋友可以参考下
    2023-11-11
  • java如何获得redis所有的key-value

    java如何获得redis所有的key-value

    这篇文章主要介绍了java如何获得redis所有的key-value,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • 浅谈一下数据库连接池Druid德鲁伊

    浅谈一下数据库连接池Druid德鲁伊

    数据库连接池就是一个容器持有多个数据库连接,当程序需要操作数据库的时候直接从池中取出连接,使用完之后再还回去,和线程池一个道理,需要的朋友可以参考下
    2023-05-05
  • 解决nacos项目启动报错:Connection refused: no further informa问题

    解决nacos项目启动报错:Connection refused: no further&

    这篇文章主要介绍了解决nacos项目启动报错:Connection refused: no further informa问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • java执行bat命令碰到的阻塞问题的解决方法

    java执行bat命令碰到的阻塞问题的解决方法

    这篇文章主要介绍了java执行bat命令碰到的阻塞问题的解决方法,有需要的朋友可以参考一下
    2014-01-01
  • springboot中EasyPoi实现自动新增序号的方法

    springboot中EasyPoi实现自动新增序号的方法

    本文主要介绍了EasyPoi实现自动新增序号,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论