java写一个大文件分片下载的前端和后端程序
时间: 2023-05-30 15:08:00 浏览: 319
由于您没有给出具体的技术要求和文件分片下载的实现方式,我将提供一种Java Web环境下使用HTTP协议实现大文件分片下载的前端和后端程序。
前端程序:
1. HTML页面
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>大文件分片下载</title>
</head>
<body>
<h1>大文件分片下载</h1>
<form id="download-form">
<label for="url-input">请输入文件下载链接:</label>
<input id="url-input" type="text" name="url" required>
<br><br>
<label for="thread-input">请输入下载线程数:</label>
<input id="thread-input" type="number" name="thread" min="1" value="1" required>
<br><br>
<button type="submit">开始下载</button>
</form>
<div id="progress-bar" style="width: 0%; height: 20px; background-color: #0f0;"></div>
<div id="progress-text">0%</div>
<br><br>
<a id="download-link" style="display: none;">点击此处下载文件</a>
<script src="download.js"></script>
</body>
</html>
```
2. JavaScript代码
```javascript
const downloadForm = document.getElementById('download-form');
const progressBar = document.getElementById('progress-bar');
const progressText = document.getElementById('progress-text');
const downloadLink = document.getElementById('download-link');
downloadForm.addEventListener('submit', (event) => {
event.preventDefault();
const url = downloadForm.url.value;
const thread = downloadForm.thread.value;
startDownload(url, thread);
});
function startDownload(url, thread) {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/download');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = () => {
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
const response = JSON.parse(xhr.responseText);
if (response.success) {
downloadLink.href = response.downloadUrl;
downloadLink.style.display = 'block';
} else {
alert(response.message);
}
} else {
alert('下载失败,请重试!');
}
}
};
xhr.upload.onprogress = (event) => {
progressBar.style.width = `${event.loaded / event.total * 100}%`;
progressText.innerHTML = `${event.loaded / event.total * 100}%`;
};
xhr.send(JSON.stringify({url, thread}));
}
```
后端程序:
1. Maven依赖
```xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
```
2. Spring Boot配置
```java
@Configuration
public class AppConfig {
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(10);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("download-thread-");
executor.initialize();
return executor;
}
}
```
3. Controller代码
```java
@RestController
public class DownloadController {
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
@PostMapping("/download")
public ResponseEntity<?> download(@RequestBody DownloadRequest request) throws IOException {
String downloadUrl = request.getUrl();
int threadCount = request.getThread();
if (downloadUrl == null || downloadUrl.isEmpty()) {
return ResponseEntity.badRequest().body(new DownloadResponse(false, "下载链接不能为空!"));
}
if (threadCount <= 0) {
return ResponseEntity.badRequest().body(new DownloadResponse(false, "下载线程数必须大于0!"));
}
String filename = downloadUrl.substring(downloadUrl.lastIndexOf('/') + 1);
File file = new File(filename);
if (file.exists()) {
file.delete();
}
HttpURLConnection connection = (HttpURLConnection) new URL(downloadUrl).openConnection();
connection.setRequestMethod("HEAD");
long fileSize = connection.getContentLengthLong();
connection.disconnect();
if (fileSize < 0) {
return ResponseEntity.badRequest().body(new DownloadResponse(false, "获取文件大小失败!"));
}
long blockSize = fileSize / threadCount + 1;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
long start = i * blockSize;
long end = i == threadCount - 1 ? fileSize - 1 : (i + 1) * blockSize - 1;
taskExecutor.execute(() -> {
try {
HttpURLConnection conn = (HttpURLConnection) new URL(downloadUrl).openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Range", "bytes=" + start + "-" + end);
InputStream inputStream = conn.getInputStream();
RandomAccessFile output = new RandomAccessFile(file, "rw");
output.seek(start);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
output.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
latch.countDown();
}
});
}
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
return ResponseEntity.ok(new DownloadResponse(true, "下载成功!", filename));
}
public static class DownloadRequest {
private String url;
private int thread;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public int getThread() {
return thread;
}
public void setThread(int thread) {
this.thread = thread;
}
}
public static class DownloadResponse {
private boolean success;
private String message;
private String downloadUrl;
public DownloadResponse(boolean success, String message) {
this.success = success;
this.message = message;
}
public DownloadResponse(boolean success, String message, String downloadUrl) {
this.success = success;
this.message = message;
this.downloadUrl = downloadUrl;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getDownloadUrl() {
return downloadUrl;
}
public void setDownloadUrl(String downloadUrl) {
this.downloadUrl = downloadUrl;
}
}
}
```
阅读全文