1.java多线程通过多个路径压缩为一个zip文件
import lombok.Data;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
* @author lyr
* @date 2020-05-25
*/
@RestController
@RequestMapping("/mergeFile")
public class MergeFileController {
@RequestMapping("/m")
public void mergeFile(/*@RequestBody List<String> paths,*/ HttpServletRequest request, HttpServletResponse response) throws IOException {
//待压缩文件的全路径地址集合
List<String> paths = new ArrayList<>();
paths.add("D:\\ce1.txt");
paths.add("D:\\ce2.txt");
ZipOutputStream zipOutputStream = null;
try {
if (CollectionUtils.isEmpty(paths)) {
return;
}
int count = paths.size();
final CountDownLatch countDownLatch = new CountDownLatch(count);
ExecutorService pools = Executors.newWorkStealingPool();
List<TempData> lists = new ArrayList<>(count);
paths.forEach(p -> {
WorkCallable workCallable = new WorkCallable(p);
Future<BufferedInputStream> submit = pools.submit(workCallable);
countDownLatch.countDown();
try {
TempData tempData = new TempData();
tempData.setBis(submit.get());
tempData.setPath(p);
lists.add(tempData);
} catch (Exception e) {
e.printStackTrace();
}
});
if (CollectionUtils.isEmpty(lists)) {
return;
}
//压缩后的zip包名
String zipName = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE) + ".zip";
packageResponse(request, response, zipName);
zipOutputStream = new ZipOutputStream(response.getOutputStream());
zipOutputStream.setMethod(ZipOutputStream.DEFLATED);
final int BUFFER = 1024;
for (TempData tempData : lists) {
try {
ZipEntry entry = new ZipEntry(new File(tempData.getPath()).getName());
zipOutputStream.putNextEntry(entry);
byte[] data = new byte[BUFFER];
while ((tempData.getBis().read(data, 0, BUFFER)) != -1) {
zipOutputStream.write(data, 0, data.length);
}
} catch (Exception e) {
throw e;
} finally {
tempData.getBis().close();
tempData.getBis().close();
zipOutputStream.flush();
zipOutputStream.closeEntry();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != zipOutputStream) {
zipOutputStream.close();
}
}
}
private void packageResponse(HttpServletRequest request, HttpServletResponse response, String zipName) throws UnsupportedEncodingException {
response.setHeader("content-type", "application/octet-stream");
response.setCharacterEncoding("utf-8");
final String userAgent = request.getHeader("user-agent");
boolean flag = null != userAgent && (userAgent.indexOf("Firefox") >= 0
|| userAgent.indexOf("Chrome") >= 0 || userAgent.indexOf("Safari") >= 0);
if (flag) {
zipName = new String(zipName.getBytes(), "ISO8859-1");
} else {
zipName = URLEncoder.encode(zipName, "UTF8");
}
response.setHeader("Content-disposition",
"attachment;filename=" + new String(zipName.getBytes("gbk"), "iso8859-1"));
}
}
class WorkCallable implements Callable<BufferedInputStream> {
private String path;
public WorkCallable(String path) {
this.path = path;
}
@Override
public BufferedInputStream call() throws Exception {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(path));
return bis;
}
}
class TempData {
private BufferedInputStream bis;
private String path;
public BufferedInputStream getBis() {
return bis;
}
public void setBis(BufferedInputStream bis) {
this.bis = bis;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}