概要
java环境下通过远程接口实现文件下载几种方式:
- 使用NIO下载文件, 需要 jdk 1.7+
- 利用 commonio 库下载文件,依赖Apache Common IO
- 文件通道FileChahhel
- 通过URL直接下载转换成MultipartFile
- 接口服务直接返回文件流
需要具备参数
- 文件内容
- 保存地址
- 文件名称类型(后缀)
实现的四种方式:
使用NIO下载文件
/**
* 使用NIO下载文件, 需要 jdk 1.7+
* @param url 下载地址
* @param saveDir 保存地址
* @param fileName 文件名称
*/
public static void downloadByNIO(String url, String saveDir, String fileName) {
try (InputStream ins = new UrlResource(url).getInputStream()) {
Path target = Paths.get(saveDir, fileName);
Files.createDirectories(target.getParent());
Files.copy(ins, target, StandardCopyOption.REPLACE_EXISTING);
} catch (IOException e) {
log.error("文件下载失败:" + e.getMessage());
throw new RuntimeException("downloadByNIO error from remoteUrl", e);
}
}
利用Apache common io 库下载文件
/**
* 利用 commonio 库下载文件,依赖Apache Common IO
* @param url 下载地址
* @param saveDir 保存地址
* @param fileName 文件名称
*/
public static void downloadByApacheCommonIO(String url, String saveDir, String fileName) {
try {
FileUtils.copyURLToFile(new URL(url), new File(saveDir, fileName));
} catch (IOException e) {
log.error("文件下载失败:" + e.getMessage());
throw new RuntimeException("downloadByApacheCommonIO error from remoteUrl", e);
}
}
使用文件通道FileChahhel下载文件
/**
* 文件下载
* 使用文件通道FileChahhel下载文件
* @param downloadUrl 下载地址
*/
public static void downloadFileByChannel(String downloadUrl, String tempPath) {
ReadableByteChannel readableByteChannel;
FileUtil.createTempFile(new File(tempPath));
try (FileChannel fileChannel = new FileOutputStream(FileUtil.createTempFile(new File(tempPath))).getChannel()){
URL url = new URL(downloadUrl);
readableByteChannel = Channels.newChannel(new BufferedInputStream(url.openStream()));
fileChannel.transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (Exception e) {
log.error("文件下载失败:" + e.getMessage());
throw new RuntimeException("downloadFileByChannel error from downloadUrl", e);
}
}
通过URL直接转换成MutipartFile
public static MultipartFile getFileFromUrl(String url, String fileName) throws IOException {
// Create a resource from the URL
URL urlObj = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlObj.openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(10000);
connection.setReadTimeout(60000);
connection.setDoOutput(true);
DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
DiskFileItem fileItem = (DiskFileItem) fileItemFactory.createItem("file",
MediaType.ALL_VALUE, true, fileName);
fileItem.getOutputStream().flush();
try (ReadableByteChannel readableByteChannel = Channels.newChannel(connection.getInputStream());
OutputStream outputStream = fileItem.getOutputStream();
WritableByteChannel writableByteChannel = Channels.newChannel(outputStream)) {
// Create a byte buffer to store the file content
ByteBuffer buffer = ByteBuffer.allocateDirect(1024 << 2);
// Read the file content into the byte buffer
while (readableByteChannel.read(buffer) != -1) {
// Prepare the byte buffer to be read again
buffer.flip();
while (buffer.hasRemaining()) {
writableByteChannel.write(buffer);
}
buffer.clear();
}
} catch (Exception e) {
// Handle network or file IO exceptions here
log.error("Error uploading file", e);
throw e;
}
return new CommonsMultipartFile(fileItem);
}
接口服务直接返回文件流
@PostMapping("/download")
public ResponseEntity<InputStreamResource> downloadFile(String url) throws IOException {
// 从远程地址下载文件流
URL remoteUrl = new URL(url);
URLConnection connection = remoteUrl.openConnection();
ReadableByteChannel readableByteChannel = Channels.newChannel(connection.getInputStream());
// 设置响应头信息
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment; filename=" + url.substring(url.lastIndexOf("/") + 1));
MediaType mediaType = ObjectUtils.defaultIfNull(MediaType.parseMediaType(connection.getContentType()), MediaType.APPLICATION_OCTET_STREAM);
// 返回文件流给请求端
return ResponseEntity.ok()
.headers(headers)
.contentType(mediaType)
.body(new InputStreamResource(Channels.newInputStream(readableByteChannel)));
}
小结
这里没有小洁