多线程测试
This commit is contained in:
parent
989157a852
commit
e41998b0c5
|
|
@ -0,0 +1,25 @@
|
|||
package com.github.catvod.utils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class DownloadInfo {
|
||||
|
||||
private List<long[]> parts;
|
||||
private String url;
|
||||
|
||||
public List<long[]> getParts() {
|
||||
return parts;
|
||||
}
|
||||
|
||||
public void setParts(List<long[]> parts) {
|
||||
this.parts = parts;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
package com.github.catvod.utils;
|
||||
|
||||
|
||||
import com.github.catvod.crawler.SpiderDebug;
|
||||
import com.github.catvod.net.OkHttp;
|
||||
import okhttp3.Response;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class DownloadService {
|
||||
private static final int THREAD_NUM = 16;
|
||||
//最小分片,按这个下载
|
||||
private static final int PER_PIECE = 1024 * 1024;
|
||||
//按照这个分割视频,每一个部分多线程下载,下载完下载下一个部分
|
||||
private static final int PER_PART = 1024 * 1024 * THREAD_NUM;
|
||||
private List<Future<Response>> results = new ArrayList<Future<Response>>();
|
||||
private RandomAccessFile file = null;
|
||||
private List<long[]> parts;
|
||||
private AtomicInteger index = new AtomicInteger(0);
|
||||
|
||||
private static class Loader {
|
||||
static volatile DownloadService INSTANCE = new DownloadService();
|
||||
}
|
||||
|
||||
public static DownloadService get() {
|
||||
return DownloadService.Loader.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载链接
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 下载信息
|
||||
*/
|
||||
private DownloadInfo downloadInfo;
|
||||
|
||||
|
||||
public void submitDownload(String url, Map<String, String> headers, long length) {
|
||||
if (url.equals(this.url)) {
|
||||
SpiderDebug.log("url相同,任务已存在");
|
||||
} else {
|
||||
this.url = url;
|
||||
parts = generatePart(length);
|
||||
downloadInfo = new DownloadInfo();
|
||||
downloadInfo.setParts(parts);
|
||||
downloadInfo.setUrl(url);
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
ExecutorService service = Executors.newFixedThreadPool(THREAD_NUM);
|
||||
|
||||
for (long[] part : parts) {
|
||||
String newRange = "bytes=" + part[0] + "-" + part[1];
|
||||
SpiderDebug.log("下载开始" + ";newRange:" + newRange);
|
||||
|
||||
Map<String, String> headerNew = new HashMap<>(headers);
|
||||
|
||||
headerNew.put("range", newRange);
|
||||
headerNew.put("Range", newRange);
|
||||
Future<Response> result = service.submit(() -> {
|
||||
try {
|
||||
part[2] = 1;
|
||||
return OkHttp.newCall(url, headerNew);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
results.add(result);
|
||||
}
|
||||
try {
|
||||
file = new RandomAccessFile(Path.tv() + File.separator + Util.MD5(url) + ".mp4", "rw");
|
||||
} catch (FileNotFoundException e) {
|
||||
SpiderDebug.log("创建文件失败");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
|
||||
while (index.get() < results.size()) {
|
||||
Response response = null;
|
||||
try {
|
||||
response = results.get(index.get()).get();
|
||||
file.seek(parts.get(index.get())[0]);
|
||||
file.write(response.body().bytes());
|
||||
index.addAndGet(1);
|
||||
} catch (ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
service.shutdown();
|
||||
}
|
||||
}).start();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回信息
|
||||
*
|
||||
* @param start 开始
|
||||
* @return
|
||||
*/
|
||||
public Object[] getDownloadBytes(long start) throws ExecutionException, InterruptedException {
|
||||
long partIndex = start / PER_PART;
|
||||
|
||||
while (parts.get((int) partIndex)[2] == 0) {
|
||||
index.set((int) partIndex);
|
||||
}
|
||||
try {
|
||||
file.seek(start);
|
||||
byte[] bytes = new byte[Math.toIntExact(parts.get((int) partIndex)[1] - start + 1)];
|
||||
file.read(bytes);
|
||||
return new Object[]{bytes,start,parts.get((int) partIndex)[1] };
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 分割为需要下载的部分
|
||||
*
|
||||
* @param total 文件总大小
|
||||
* @return
|
||||
*/
|
||||
private static List<long[]> generatePart(long total) {
|
||||
SpiderDebug.log("generatePart.total:" + total);
|
||||
|
||||
long start = 0;
|
||||
long end = total - 1;
|
||||
|
||||
//分割为多少个部分
|
||||
long size = total / PER_PART;
|
||||
SpiderDebug.log("generatePart.size:" + size);
|
||||
List<long[]> partList = new ArrayList<>();
|
||||
for (int i = 0; i < size * THREAD_NUM; i++) {
|
||||
long partEnd = Math.min(start + PER_PIECE, end);
|
||||
|
||||
partList.add(new long[]{start, partEnd, 0});
|
||||
start = partEnd + 1;
|
||||
}
|
||||
|
||||
//最后多出分为一块下载
|
||||
if (start <= end) {
|
||||
partList.add(new long[]{start, end, 0});
|
||||
}
|
||||
return partList;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
package com.github.catvod.utils;
|
||||
|
||||
import com.github.catvod.server.Server;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class ProxyVideoTest {
|
||||
|
||||
@Test
|
||||
public void proxyMultiThread() {
|
||||
// ProxyVideo.proxyMultiThread()
|
||||
Server.get().start();
|
||||
String url = ProxyVideo.buildCommonProxyUrl(
|
||||
"http://172.16.1.217:18089/ng-grid/video.mp4", new HashMap<>());
|
||||
System.out.println(url);
|
||||
while (true) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue