大家好,又见面了,我是你们的朋友全栈君。
最近接到一个需求,就是将远程目录下的文件或文件夹下载到指定目录下,下面来看下最后的成果。
1.首先,IO流输出文件(可以在浏览器端下载)
public HttpServletResponse download(String fileName, HttpServletResponse response) {
File file = new File(gitConfig.getDestPath() + "/" + fileName);
if (file.isDirectory()){
return downDestroy(file, response);
}else{
return downFile(file,response);
}
}
/**
* 下载文件
* @param file
* @param response
* @return
*/
private HttpServletResponse downFile(File file, HttpServletResponse response) {
InputStream fis = null;
OutputStream toClient = null;
try {
// 以流的形式下载文件。
fis = new BufferedInputStream(new FileInputStream(file.getPath()));
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
// 清空response
response.reset();
toClient = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
//如果输出的是中文名的文件,在此处就要用URLEncoder.encode方法进行处理
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "UTF-8"));
toClient.write(buffer);
toClient.flush();
} catch (IOException ex) {
ex.printStackTrace();
}finally{
try {
File f = new File(file.getPath());
f.delete();
if(fis!=null){
fis.close();
}
if(toClient!=null){
toClient.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
/**
* 下载文件夹
* @param file
* @param response
* @return
*/
private HttpServletResponse downDestroy(File file, HttpServletResponse response) {
String zipFilePath = gitConfig.getDestPath()+"/"+file.getName()+"_"+System.currentTimeMillis()/1000+".zip";
ZipCompressor zipCompressor = new ZipCompressor(zipFilePath);
try {
zipCompressor.compress(file.getPath());
File zipFile = new File(zipFilePath);
downFile(zipFile,response);
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
对应的工具类
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* 压缩类
*
*/
public class ZipCompressor {
static final int BUFFER = 8192;
/**
* 压缩的文件夹
*/
private File zipFile;
public ZipCompressor(String pathName) {
zipFile = new File(pathName);
}
/**
* 遍历需要压缩文件集合
* @param pathName
* @throws IOException
*/
public void compress(String... pathName) throws IOException {
ZipOutputStream out =null;
FileOutputStream fileOutputStream=null;
CheckedOutputStream cos=null;
try {
fileOutputStream = new FileOutputStream(zipFile);
cos = new CheckedOutputStream(fileOutputStream,new CRC32());
out = new ZipOutputStream(cos);
String basedir = "";
for (int i=0;i<pathName.length;i++){
compress(new File(pathName[i]), out, basedir);
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
if(out!=null){
out.close();
}
if(fileOutputStream!=null){
fileOutputStream.close();
}
if(cos!=null){
cos.close();
}
}
}
/**
* 压缩
* @param file
* @param out
* @param basedir
*/
private void compress(File file, ZipOutputStream out, String basedir) throws IOException {
// 判断是目录还是文件
if (file.isDirectory()) {
this.compressDirectory(file, out, basedir);
} else {
this.compressFile(file, out, basedir);
}
}
/**
* 压缩一个目录
* */
private void compressDirectory(File dir, ZipOutputStream out, String basedir) throws IOException {
if (!dir.exists()){
return;
}
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
// 递归
compress(files[i], out, basedir + dir.getName() + "/");
}
}
/**
* 压缩一个文件
*
* */
private void compressFile(File file, ZipOutputStream out, String basedir) throws IOException {
if (!file.exists()) {
return;
}
BufferedInputStream bis =null;
try {
bis = new BufferedInputStream(new FileInputStream(file));
ZipEntry entry = new ZipEntry(basedir + file.getName());
out.putNextEntry(entry);
int count;
byte[] data = new byte[BUFFER];
while ((count = bis.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
} catch (Exception e) {
throw new RuntimeException(e);
}finally {
if(bis!=null){
bis.close();
}
}
}
}
2.接收IO文件流,并保存到本地(文件夹类接收的是压缩文件,接收完之后会将压缩文件解压然后删除压缩文件)
public void downFileOrDestroy(String fileName){
boolean isfile = true;
if (fileName.indexOf(".")==-1){
//如果是文件夹
isfile =false;
}
String pluginsDir = "D:/file";
URL urlfile = null;
HttpURLConnection httpUrl = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
File path = new File(pluginsDir);
if (!path.exists()){
path.mkdirs();
}
File f = null;
if (isfile){
f = new File(pluginsDir+"/"+fileName);
}else{
f = new File(pluginsDir+File.separator+fileName+"_"+System.currentTimeMillis()/1000+".zip");
}
try {
urlfile = new URL("文件IO输出接口地址?fileName="+fileName);
httpUrl = (HttpURLConnection) urlfile.openConnection();
httpUrl.connect();
InputStream inputStream = httpUrl.getInputStream();
bis = new BufferedInputStream(inputStream);
FileOutputStream fileOutputStream = new FileOutputStream(f);
bos = new BufferedOutputStream(fileOutputStream);
int len = 2048;
byte[] b = new byte[len];
while ((len = bis.read(b)) != -1) {
bos.write(b, 0, len);
}
bos.flush();
bos.close();
bis.close();
httpUrl.disconnect();
if (!isfile){
//如果是文件夹,下载下来的是压缩文件,要解压文件
ZipUtil.unZipUncompress(f.getPath(),pluginsDir);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bis.close();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
涉及到的工具类:
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
/**
* @Author cs
* @Date 2020/12/31 11:51
* @Version 1.0
*/
public class ZipUtil {
/**
* zip文件解压
* @param inputFile 待解压文件夹/文件
* @param destDirPath 解压路径
*/
public static void unZipUncompress(String inputFile,String destDirPath){
File srcFile = new File(inputFile);//获取当前压缩文件
InputStream is = null;
FileOutputStream fos = null;
try{
// 判断源文件是否存在
if (!srcFile.exists()) {
throw new Exception(srcFile.getPath() + "所指文件不存在");
}
ZipFile zipFile = new ZipFile(srcFile);//创建压缩文件对象
//开始解压
Enumeration<?> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = (ZipEntry) entries.nextElement();
// 如果是文件夹,就创建个文件夹
if (entry.isDirectory()) {
srcFile.mkdirs();
} else {
// 如果是文件,就先创建一个文件,然后用io流把内容copy过去
File targetFile = new File(destDirPath + "/" + entry.getName());
// 保证这个文件的父文件夹必须要存在
if (!targetFile.getParentFile().exists()) {
targetFile.getParentFile().mkdirs();
}
targetFile.createNewFile();
// 将压缩文件内容写入到这个文件中
is = zipFile.getInputStream(entry);
fos = new FileOutputStream(targetFile);
int len;
byte[] buf = new byte[1024];
while ((len = is.read(buf)) != -1) {
fos.write(buf, 0, len);
}
// 关流顺序,先打开的后关闭
fos.close();
is.close();
}
}
zipFile.close();
}catch (Exception e){
e.printStackTrace();
}finally {
//删除压缩文件
boolean delete = srcFile.delete();
System.out.println(delete);
}
}
}
有的朋友可能会遇到临时文件删除不掉的问题,一般出现这种情况的原因都是IO没关闭,检查下自己的代码,先打开的IO后关闭,按顺序关闭IO即可解决。
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/156955.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...