码上敲享录 > java入门知识分享 > java下载如何限速

java下载如何限速

上一章章节目录下一章 2019-01-14已有3090人阅读 评论(0)

java下载如何限速


解决方法:

1.核心方法

public static AtomicInteger downloadNum = new AtomicInteger();

@RequestMapping("/downloadFile")

public void downloadFile(HttpServletRequest request,HttpServletResponse response) {

downloadNum.incrementAndGet();  // 请求计数器 +1

OutputStream out = null;

InputStream fileInputStream  = null;

DownloadLimiter downloadLimiter = null;

try {

String export_url ="F:/0f000Aq540QOO1Ne4OcXa6.xls";

String fileName=export_url.substring(export_url.lastIndexOf("/")+1);

response.setContentType("application/octet-stream");

response.setHeader("Content-Disposition","attachment; filename=" + fileName);

fileInputStream = new FileInputStream(export_url );

//计算下载速度  总共的带宽是2M 速度是256KB/s

int downloadSpeed = 256/downloadNum.get();

BandwidthLimiter bandwidthLimiter = new BandwidthLimiter(downloadSpeed);

downloadLimiter = new DownloadLimiter(fileInputStream, bandwidthLimiter);

   out = response.getOutputStream();

   int len =0;

while((len=downloadLimiter.read()) != -1){

out.write(len);

bandwidthLimiter.setMaxRate(256/downloadNum.get());

}

out.flush();

out.close();

downloadLimiter.close();    

} catch (IOException e) {

}finally{

if(fileInputStream !=null){

try {

fileInputStream.close();

} catch (IOException e) {

}

}

if(out !=null){

try {

out.close();

} catch (IOException e) {

}

}

if(downloadLimiter !=null){

try {

downloadLimiter.close();

} catch (IOException e) {

}

}

downloadNum.decrementAndGet();   // 请求计数器 -1

}

}


2.DownloadLimiter.java源码

import java.io.IOException;

import java.io.InputStream;


public class DownloadLimiter extends InputStream {

private InputStream is = null;

private BandwidthLimiter bandwidthLimiter = null;


public DownloadLimiter(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);

}

}


3.BandwidthLimiter.java源码

public class BandwidthLimiter {


/* 1024KB */

private static Long KB = 1024l;


/* 以字节计算的最小计数块长度 */

private static Long CHUNK_LENGTH = 1024l;


/* 将发送或接收多少字节 */

private int bytesWillBeSentOrReceive = 0;


/* 当最后一块被发送或接收时 */

private long lastPieceSentOrReceiveTick = System.nanoTime();


/* 默认的速度是 1024KB/s */

private int maxRate = 256; //2M带宽是256KB/s


/* 时间成本来发送 CHUNK_LENGTH 字节纳秒 */

private long timeCostPerChunk = (1000000000l * CHUNK_LENGTH) / (this.maxRate * KB);


/**

* 初始化 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.

*

* 设置一个最大的下载速度,如果速度是0,这意味着没有带宽限制

* @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);

}


/**

* 下一个len字节应该做带宽限制

*

* @param len

*/

public synchronized void limitNextBytes(int len) {

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.sleep(missedTime / 1000000, (int) (missedTime % 1000000));

} catch (InterruptedException e) {

e.printStackTrace();

}

}

this.bytesWillBeSentOrReceive -= CHUNK_LENGTH;

this.lastPieceSentOrReceiveTick = nowTick + (missedTime > 0 ? missedTime : 0);

}

}

}

本文链接:http://www.yayihouse.com/yayishuwu/chapter/1767
向大家推荐《Activiti工作流实战教程》:https://xiaozhuanlan.com/activiti
0

有建议,请留言!

  • *您的姓名:

  • *所在城市:

  • *您的联系电话:

    *您的QQ:

  • 咨询问题:

  • 提 交