use of de.schlichtherle.util.zip.ZipOutputStream in project otter by alibaba.
the class ArchiveBean method doPack.
/**
* 执行压缩
*/
@SuppressWarnings("resource")
private boolean doPack(final File targetArchiveFile, List<FileData> fileDatas, final ArchiveRetriverCallback<FileData> callback) {
// 首先判断下对应的目标文件是否存在,如存在则执行删除
if (true == targetArchiveFile.exists() && false == NioUtils.delete(targetArchiveFile, 3)) {
throw new ArchiveException(String.format("[%s] exist and delete failed", targetArchiveFile.getAbsolutePath()));
}
boolean exist = false;
ZipOutputStream zipOut = null;
Set<String> entryNames = new HashSet<String>();
// 下载成功的任务列表
BlockingQueue<Future<ArchiveEntry>> queue = new LinkedBlockingQueue<Future<ArchiveEntry>>();
ExecutorCompletionService completionService = new ExecutorCompletionService(executor, queue);
final File targetDir = new File(targetArchiveFile.getParentFile(), FilenameUtils.getBaseName(targetArchiveFile.getPath()));
try {
// 创建一个临时目录
FileUtils.forceMkdir(targetDir);
zipOut = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(targetArchiveFile)));
zipOut.setLevel(Deflater.BEST_SPEED);
// 进行并发压缩处理
for (final FileData fileData : fileDatas) {
if (fileData.getEventType().isDelete()) {
// 忽略delete类型的数据打包,因为只需直接在目标进行删除
continue;
}
String namespace = fileData.getNameSpace();
String path = fileData.getPath();
boolean isLocal = StringUtils.isBlank(namespace);
String entryName = null;
if (true == isLocal) {
entryName = FilenameUtils.getPath(path) + FilenameUtils.getName(path);
} else {
entryName = namespace + File.separator + path;
}
// 过滤一些重复的文件数据同步
if (entryNames.contains(entryName) == false) {
entryNames.add(entryName);
} else {
continue;
}
final String name = entryName;
if (true == isLocal && !useLocalFileMutliThread) {
// 采用串行处理,不走临时文件
queue.add(new DummyFuture(new ArchiveEntry(name, callback.retrive(fileData))));
} else {
completionService.submit(new Callable<ArchiveEntry>() {
public ArchiveEntry call() throws Exception {
// 处理下异常,可能失败
InputStream input = null;
OutputStream output = null;
try {
input = callback.retrive(fileData);
if (input instanceof LazyFileInputStream) {
// 获取原始的stream
input = ((LazyFileInputStream) input).getInputSteam();
}
if (input != null) {
File tmp = new File(targetDir, name);
// 尝试创建父路径
NioUtils.create(tmp.getParentFile(), false, 3);
output = new FileOutputStream(tmp);
// 拷贝到文件
NioUtils.copy(input, output);
return new ArchiveEntry(name, new File(targetDir, name));
} else {
return new ArchiveEntry(name);
}
} finally {
IOUtils.closeQuietly(input);
IOUtils.closeQuietly(output);
}
}
});
}
}
for (int i = 0; i < entryNames.size(); i++) {
// 读入流
ArchiveEntry input = null;
InputStream stream = null;
try {
input = queue.take().get();
if (input == null) {
continue;
}
stream = input.getStream();
if (stream == null) {
continue;
}
if (stream instanceof LazyFileInputStream) {
// 获取原始的stream
stream = ((LazyFileInputStream) stream).getInputSteam();
}
exist = true;
zipOut.putNextEntry(new ZipEntry(input.getName()));
// 输出到压缩流中
NioUtils.copy(stream, zipOut);
zipOut.closeEntry();
} finally {
IOUtils.closeQuietly(stream);
}
}
if (exist) {
zipOut.finish();
}
} catch (Exception e) {
throw new ArchiveException(e);
} finally {
IOUtils.closeQuietly(zipOut);
try {
// 删除临时目录
FileUtils.deleteDirectory(targetDir);
} catch (IOException e) {
// ignore
}
}
return exist;
}
Aggregations