package com.wnsys.admin.limiter; import com.wnsys.admin.util.FileDownloadUtils; /** * @Author: zhuquanwen * @Description: * @Date: 2018/3/8 16:54 * @Modified: **/ public class BandwidthLimiter { public static int maxBandWith = 2 * 1024; //KB /* KB */ private static Long KB = 1024l; /* The smallest count chunk length in bytes */ private static Long CHUNK_LENGTH = 1024l; /* How many bytes will be sent or receive */ private int bytesWillBeSentOrReceive = 0; /* When the last piece was sent or receive */ private long lastPieceSentOrReceiveTick = System.nanoTime(); /* Default rate is 1024KB/s */ private int maxRate = 1024; /* Time cost for sending CHUNK_LENGTH bytes in nanoseconds */ private long timeCostPerChunk = (1000000000l * CHUNK_LENGTH) / (this.maxRate * KB); /** * Initialize a BandwidthLimiter object with a certain rate. * * @param maxRate the download or upload speed in KBytes */ public BandwidthLimiter(int maxRate) { this.setMaxRate(maxRate); } /** * Set the max upload or download rate in KB/s. maxRate must be grater than * 0. If maxRate is zero, it means there is no bandwidth limit. * * @param maxRate If maxRate is zero, it means there is no bandwidth limit. * @throws IllegalArgumentException */ public synchronized void setMaxRate(int maxRate) throws IllegalArgumentException { if (maxRate < 0) { throw new IllegalArgumentException("maxRate can not less than 0"); } this.maxRate = maxRate < 0 ? 0 : maxRate; if (maxRate == 0) this.timeCostPerChunk = 0; else this.timeCostPerChunk = (1000000000l * CHUNK_LENGTH) / (this.maxRate * KB); } /** * Next 1 byte should do bandwidth limit. */ public synchronized void limitNextBytes() { this.limitNextBytes(1); } /** * Next len bytes should do bandwidth limit * * @param len */ public synchronized void limitNextBytes(int len) { int online = FileDownloadUtils.onlineDownloadNumber.get(); int max = online> 0 ? BandwidthLimiter.maxBandWith/online : BandwidthLimiter.maxBandWith; setMaxRate(max); this.bytesWillBeSentOrReceive += len; /* We have sent CHUNK_LENGTH bytes */ while (this.bytesWillBeSentOrReceive > CHUNK_LENGTH) { long nowTick = System.nanoTime(); long missedTime = this.timeCostPerChunk - (nowTick - this.lastPieceSentOrReceiveTick); if (missedTime > 0) { try { Thread.currentThread().sleep(missedTime / 1000000, (int) (missedTime % 1000000)); } catch (InterruptedException e) { e.printStackTrace(); } } this.bytesWillBeSentOrReceive -= CHUNK_LENGTH; this.lastPieceSentOrReceiveTick = nowTick + (missedTime > 0 ? missedTime : 0); } }
}
package com.wnsys.admin.limiter; import java.io.IOException; import java.io.InputStream; /** * @Author: zhuquanwen * @Description: * @Date: 2018/3/8 17:06 * @Modified: **/ public class LimiterInputStream extends InputStream { private InputStream is = null; private BandwidthLimiter bandwidthLimiter = null; public LimiterInputStream(InputStream is, BandwidthLimiter bandwidthLimiter) { this.is = is; this.bandwidthLimiter = bandwidthLimiter; } @Override public int read() throws IOException { if (this.bandwidthLimiter != null) this.bandwidthLimiter.limitNextBytes(); return this.is.read(); } public int read(byte b[], int off, int len) throws IOException { if (bandwidthLimiter != null) bandwidthLimiter.limitNextBytes(len); return this.is.read(b, off, len); } }
package com.wnsys.admin.limiter; import java.io.IOException; import java.io.OutputStream; /** * @Author: zhuquanwen * @Description: * @Date: 2018/3/9 9:01 * @Modified: **/ public class LimiterOutputStream extends OutputStream { private OutputStream os = null; private BandwidthLimiter bandwidthLimiter = null; public LimiterOutputStream(OutputStream os, BandwidthLimiter bandwidthLimiter) { this.os = os; this.bandwidthLimiter = bandwidthLimiter; } @Override public void write(int b) throws IOException { if (bandwidthLimiter != null) bandwidthLimiter.limitNextBytes(); this.os.write(b); } public void write(byte[] b, int off, int len) throws IOException { if (bandwidthLimiter != null) bandwidthLimiter.limitNextBytes(len); this.os.write(b, off, len); } }
package com.wnsys.admin.util; import com.wnsys.admin.limiter.BandwidthLimiter; import com.wnsys.admin.limiter.LimiterOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.util.concurrent.atomic.AtomicInteger; /** * @Author: zhuquanwen * @Description: 文件下载工具类 * @Date: 2018/1/18 13:57 * @Modified: **/ public class FileDownloadUtils { private static Logger logger = LoggerFactory.getLogger(FileDownloadUtils.class); public static AtomicInteger onlineDownloadNumber = new AtomicInteger(0); private FileDownloadUtils(){ } public static String transFileName(String fileName, HttpServletRequest request) throws Exception{ String agent = request.getHeader("USER-AGENT"); //fileName = fileName.trim(); //去首尾空格 //根据文件头判断请求来自的浏览器,以便有针对性的对文件名转码 if(null != agent && -1 != agent.indexOf("theworld")){ //世界之窗 fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); //解决下载的文件名中含有小括号转变义符%28%29 }else if(null != agent && -1 != agent.indexOf("MSIE 8.0")){ //IE8 String lenFileName = URLEncoder.encode(fileName, "UTF-8"); if (lenFileName.length() > 150) { //文件名长度是否大于150个字符 fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); } else { fileName = URLEncoder.encode(fileName,"UTF-8").replace("+","%20"); } }else if(null != agent && -1 != agent.indexOf("MSIE 7.0") && -1 != agent.indexOf("SE 2.X MetaSr 1.0")){ //sogo浏览器 fileName = URLEncoder.encode(fileName,"UTF-8").replace("+","%20"); }else if(null != agent && (-1 != agent.indexOf("SV1") || -1 != agent.indexOf("360SE"))){ //360安全浏览器 String lenFileName = URLEncoder.encode(fileName, "UTF-8"); if (lenFileName.length() > 150) { //文件名长度是否大于150个字符 fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); } else { fileName = URLEncoder.encode(fileName,"UTF-8").replace("+","%20"); } }else if(null != agent && -1 != agent.indexOf("Chrome")){ //google fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); //解决下载的文件名中含有小括号转变义符%28%29 }else if(null != agent && -1 != agent.indexOf("Firefox")){ //Firefox fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); }else if(null != agent && -1 != agent.indexOf("Safari")){ //Firefox fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1"); }else { //其它浏览器 fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); } return fileName; } public static void setResponseExcelHeader(HttpServletRequest request,HttpServletResponse response,String name) throws Exception { response.reset(); response.setContentType("application/octet-stream;charset=utf-8"); // 改成输出excel文件 String fileName = transFileName(name, request); response.setHeader( "Content-disposition", "attachment; filename=" +fileName); } public static void downFile(HttpServletRequest request, HttpServletResponse response, String path, String name) throws Exception{ Long fileLength = new File(path).length();// 文件的长度 if (fileLength != 0) { response.reset(); response.setContentType("application/force-download;charset=utf-8"); String fileName = transFileName(name, request); response.setHeader( "Content-disposition", "attachment; filename=" +fileName); response.setHeader("Content-Length", String.valueOf(fileLength)); try( FileInputStream fis = new FileInputStream(path); BufferedInputStream bis = new BufferedInputStream(fis); // 输出流 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ){ logger.info("文件开始下载传输"); byte[] buff = new byte[2048]; int bytesread; // 写文件 while (-1 != (bytesread = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesread); } } } } public static void downFileWithLimiter(HttpServletRequest request, HttpServletResponse response, String path, String name, int maxRate) throws Exception{ Long fileLength = new File(path).length();// 文件的长度 if (fileLength != 0) { response.reset(); response.setContentType("application/force-download;charset=utf-8"); String fileName = transFileName(name, request); response.setHeader( "Content-disposition", "attachment; filename=" +fileName); response.setHeader("Content-Length", String.valueOf(fileLength)); BandwidthLimiter bandwidthLimiter = new BandwidthLimiter(maxRate); try( FileInputStream fis = new FileInputStream(path); // LimiterInputStream limiterInput = new LimiterInputStream(fis,bandwidthLimiter); BufferedInputStream bis = new BufferedInputStream(fis); // 输出流 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); OutputStream os = new LimiterOutputStream(bos,bandwidthLimiter); ){ logger.info("文件开始下载传输"); byte[] buff = new byte[2048]; int bytesread; // 写文件 while (-1 != (bytesread = bis.read(buff, 0, buff.length))) { os.write(buff, 0, bytesread); } } } } public static void downFileWithLimiter(HttpServletRequest request, HttpServletResponse response, String path, String name) throws Exception{ int onlineNumber = onlineDownloadNumber.incrementAndGet(); int maxRate = BandwidthLimiter.maxBandWith/onlineNumber; Long fileLength = new File(path).length();// 文件的长度 if (fileLength != 0) { response.reset(); response.setContentType("application/force-download;charset=utf-8"); String fileName = transFileName(name, request); response.setHeader( "Content-disposition", "attachment; filename=" +fileName); response.setHeader("Content-Length", String.valueOf(fileLength)); BandwidthLimiter bandwidthLimiter = new BandwidthLimiter(maxRate); try{ try( FileInputStream fis = new FileInputStream(path); // LimiterInputStream limiterInput = new LimiterInputStream(fis,bandwidthLimiter); BufferedInputStream bis = new BufferedInputStream(fis); // 输出流 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); OutputStream os = new LimiterOutputStream(bos,bandwidthLimiter); ){ logger.info("文件开始下载传输"); byte[] buff = new byte[2048]; int bytesread; // 写文件 while (-1 != (bytesread = bis.read(buff, 0, buff.length))) { os.write(buff, 0, bytesread); } } }catch(Exception e){ throw e; }finally{ onlineDownloadNumber.decrementAndGet(); } } } public static void downExcelFile(HttpServletRequest request, HttpServletResponse response, String path, String name) throws Exception { Long fileLength = new File(path).length();// 文件的长度 if (fileLength != 0) { setResponseExcelHeader(request,response,name); response.setHeader("Content-Length", String.valueOf(fileLength)); try( FileInputStream fis = new FileInputStream(path); BufferedInputStream bis = new BufferedInputStream(fis); // 输出流 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ){ logger.info("文件开始下载传输"); byte[] buff = new byte[2048]; int bytesread; // 写文件 while (-1 != (bytesread = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesread); } } } } public static void downExcelStream(HttpServletRequest request, HttpServletResponse response, InputStream inputStream, String name) throws Exception { setResponseExcelHeader(request,response,name); // response.setHeader("Content-Length", String.valueOf(fileLength)); try( BufferedInputStream bis = new BufferedInputStream(inputStream); // 输出流 BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); ){ logger.info("文件开始下载传输"); byte[] buff = new byte[2048]; int bytesread; // 写文件 while (-1 != (bytesread = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesread); } } } }