使用"CloseableHttpClient httpclient = HttpClients.createDefault();"发送文件能分片发送吗
能否支持分片需要服务提供方的能力
在结束使用的时候httpClient.close()
,在close()
的时候,会对内部的pool
进行shutdowm()
,关闭所有的可用连接、正在进行的连接,释放所有的资源。
public void shutdown() throws IOException {
if (this.isShutDown) {
return ;
}
this.isShutDown = true;
this.lock.lock();
try {
for (final E entry: this.available) {
entry.close();
}
for (final E entry: this.leased) {
entry.close();
}
for (final RouteSpecificPool<T, C, E> pool: this.routeToPool.values()) {
pool.shutdown();
}
this.routeToPool.clear();
this.leased.clear();
this.available.clear();
} finally {
this.lock.unlock();
}
}
使用11个不同的请求URL
,流程示例:
关闭前
httpClient.connManager.pool
[leased: []]
[available: [
[id:10][route:{}->http://py.qianlong.com:80][state:null],
[id:9][route:{}->http://www.bnia.cn:80][state:null],
[id:8][route:{s}->https://m.you.163.com:443][state:null],
[id:7][route:{}->http://www.wenming.cn:80][state:null],
[id:6][route:{}->http://jubao.aq.163.com:80][state:null],
[id:5][route:{s}->https://www.12377.cn:443][state:null],
[id:4][route:{}->http://www.12377.cn:80][state:null],
[id:3][route:{}->http://www.bjjubao.org:80][state:null],
[id:2][route:{}->http://cimg.163.com:80][state:null],
[id:1][route:{s}->https://static.ws.126.net:443][state:null],
[id:0][route:{}->http://www.baidu.com:80][state:null]]
]
[pending: []]
关闭
18:36:51.900 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager is shutting down
18:36:51.900 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-10: Close connection
18:36:51.901 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-9: Close connection
18:36:51.901 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-8: Close connection
18:36:51.903 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-7: Close connection
18:36:51.903 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-6: Close connection
18:36:51.903 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-5: Close connection
18:36:51.904 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-4: Close connection
18:36:51.904 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-3: Close connection
18:36:51.905 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-2: Close connection
18:36:51.905 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-1: Close connection
18:36:51.906 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-0: Close connection
18:36:51.906 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection manager shut down
关闭后
httpClient.connManager.pool
[leased: []]
[available: []]
[pending: []]
可以对文件进行分片发送,具体步骤如下:
根据文件大小和分片大小进行分片,使用 FileInputStream 分别读取每个分片并传输。
可以使用 HttpComponents 中的 HttpPost 请求来上传文件,先向服务器发送一个 post 请求,获取到服务器返回的 uploadId,然后对每个分片进行上传,需要注意每个分片要有序号,上传时需要带上 uploadId 和当前分片的序号。
最后使用 HttpComponents 中的 HttpPut 请求来通知服务器合并所有分片,将分片合并成完整的文件。
以下是示例代码:
public class FileUploader {
private static final int CHUNK_SIZE = 10 * 1024 * 1024; // 默认分片大小为10MB
private String url;
private File file;
private String uploadId;
private CloseableHttpClient httpClient;
private HttpPost postRequest;
private HttpPut putRequest;
public FileUploader(String url, File file) {
this.url = url;
this.file = file;
this.httpClient = HttpClients.createDefault();
this.postRequest = new HttpPost(url);
this.putRequest = new HttpPut(url);
}
public void upload() throws IOException {
// 发送 post 请求,获取 uploadId
HttpResponse response = httpClient.execute(postRequest);
HttpEntity entity = response.getEntity();
uploadId = EntityUtils.toString(entity);
// 分片上传
int chunkCount = (int) Math.ceil((double) file.length() / CHUNK_SIZE);
for (int i = 0; i < chunkCount; i++) {
byte[] chunk = readChunk(i);
uploadChunk(chunk, i);
}
// 合并分片
completeUpload();
}
private byte[] readChunk(int chunkIndex) throws IOException {
byte[] buffer = new byte[CHUNK_SIZE];
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.skip(chunkIndex * CHUNK_SIZE);
int bytesRead = bis.read(buffer);
fis.close();
bis.close();
return Arrays.copyOf(buffer, bytesRead);
}
private void uploadChunk(byte[] chunk, int chunkNumber) throws IOException {
HttpPost request = new HttpPost(url + "?uploadId=" + uploadId + "&chunkNumber=" + chunkNumber);
ByteArrayEntity entity = new ByteArrayEntity(chunk);
request.setEntity(entity);
httpClient.execute(request);
}
private void completeUpload() throws IOException {
httpClient.execute(putRequest);
}
public static void main(String[] args) {
String url = "http://example.com/upload";
File file = new File("filename");
FileUploader uploader = new FileUploader(url, file);
try {
uploader.upload();
} catch (IOException e) {
e.printStackTrace();
}
}
}