java用线程池实现多线程上传大文件
时间: 2023-08-26 16:05:45 浏览: 133
java实现的多文件上传
4星 · 用户满意度95%
使用线程池可以更好地管理和控制多线程上传大文件的过程。下面是一个示例代码,演示了如何使用线程池实现多线程上传大文件:
```java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class FileUploader {
private ExecutorService executorService;
private String url;
public FileUploader(String url, int threadCount) {
this.url = url;
this.executorService = Executors.newFixedThreadPool(threadCount);
}
public void upload(File file) {
try {
long fileSize = file.length();
long chunkSize = (fileSize / executorService.getMaximumPoolSize()) + 1;
FileInputStream inputStream = new FileInputStream(file);
for (int i = 0; i < executorService.getMaximumPoolSize(); i++) {
long start = i * chunkSize;
long end = Math.min(start + chunkSize, fileSize);
executorService.execute(new UploadTask(url, file, start, end));
}
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void shutdown() {
executorService.shutdown();
}
private static class UploadTask implements Runnable {
private String url;
private File file;
private long start;
private long end;
public UploadTask(String url, File file, long start, long end) {
this.url = url;
this.file = file;
this.start = start;
this.end = end;
}
@Override
public void run() {
try {
HttpURLConnection connection = null;
FileInputStream inputStream = null;
OutputStream outputStream = null;
try {
URL uploadUrl = new URL(url);
connection = (HttpURLConnection) uploadUrl.openConnection();
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Range", "bytes " + start + "-" + end + "/" + file.length());
inputStream = new FileInputStream(file);
inputStream.skip(start);
outputStream = connection.getOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
int responseCode = connection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
System.out.println("上传成功:" + start + "-" + end);
} else {
System.out.println("上传失败:" + start + "-" + end);
}
} finally {
if (connection != null) {
connection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
```
使用示例:
```java
public class Main {
public static void main(String[] args) {
String url = "http://example.com/upload";
int threadCount = 4; // 线程数
FileUploader uploader = new FileUploader(url, threadCount);
File file = new File("path/to/file");
uploader.upload(file);
// 等待上传完成
uploader.shutdown();
}
}
```
在上述示例中,FileUploader类使用线程池来管理上传任务。在upload()方法中,根据文件大小和线程池的大小,将文件分成多个块,并为每个块创建一个UploadTask任务。每个任务负责上传文件的一个块。
UploadTask类实现了Runnable接口,在run()方法中执行文件上传的逻辑。每个任务在上传时设置了Content-Range请求头,指定了上传的起始位置和结束位置。
通过使用线程池,可以更好地管理和控制多线程上传大文件的过程。这样可以提高上传效率,并且能够更好地控制系统资源的使用。
阅读全文