package com.vci.web.dao.impl;
|
|
import com.vci.corba.common.PLException;
|
import com.vci.corba.volume.VolumeServicePrx;
|
import com.vci.enumpck.UI.VciFileTransProtocolEnum;
|
import com.vci.model.VciFileObjectDO;
|
import com.vci.pagemodel.VciFileObjectVO;
|
import com.vci.pagemodel.VciFileVolumeVO;
|
import com.vci.starter.web.annotation.bus.VciChangeDocument;
|
import com.vci.starter.web.exception.VciBaseException;
|
import com.vci.starter.web.pagemodel.BaseResult;
|
import com.vci.starter.web.util.LocalFileUtil;
|
import com.vci.starter.web.util.VciBaseUtil;
|
import com.vci.starter.web.wrapper.VciQueryWrapperForDO;
|
import com.vci.web.dao.VciFileObjectDaoI;
|
import com.vci.web.properties.WebProperties;
|
import com.vci.web.service.VciFileDownloadServiceI;
|
import com.vci.web.service.VciFileObjectServiceI;
|
import com.vci.web.service.VciFileVolumeServiceI;
|
import com.vci.web.util.PlatformClientUtil;
|
import com.vci.web.util.file.VciZipUtil;
|
import com.vci.web.util.file.clientutil.VciFileServerClientUtil;
|
import net.lingala.zip4j.core.ZipFile;
|
import net.lingala.zip4j.io.ZipOutputStream;
|
import org.apache.commons.lang3.StringUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.stereotype.Service;
|
import org.springframework.util.CollectionUtils;
|
|
import java.io.*;
|
import java.util.Collection;
|
import java.util.List;
|
import java.util.Map;
|
|
import static com.vci.constant.FrameWorkLangCodeConstant.*;
|
import static com.vci.constant.VciFileLangCodeConstant.FILE_NOT_FOUND;
|
import static com.vci.constant.VciFileLangCodeConstant.FILE_READ_FAIL;
|
|
/**
|
* 文件的下载服务
|
* @author weidy
|
* @date 2021-3-11
|
*/
|
@Service
|
@VciChangeDocument(btmType = "fileDownload")
|
public class VciFileDownloadServiceImpl implements VciFileDownloadServiceI {
|
|
/**
|
* 文件的对象服务
|
*/
|
@Autowired
|
private VciFileObjectServiceI vciFileObjectServiceI;
|
|
/**
|
* 文件的卷服务
|
*/
|
@Autowired
|
private VciFileVolumeServiceI vciFileVolumeServiceI;
|
|
/**
|
* 文件对象的操作
|
*/
|
@Autowired
|
private VciFileObjectDaoI vciFileObjectMapper;
|
|
/**
|
* zip操作类
|
*/
|
@Autowired
|
private VciZipUtil zipUtil;
|
|
/**
|
* 平台的客户端
|
*/
|
@Autowired
|
private PlatformClientUtil platformClientUtil;
|
|
/**
|
* 配置对象
|
*/
|
@Autowired
|
private WebProperties webProperties;
|
|
/**
|
* 根据主键下载文件,会下载到默认的临时文件夹下
|
* @param fileOids 文件的主键
|
* @return 文件在本地的全路径
|
* @throws VciBaseException 参数为空或者文件出错的时候会抛出异常
|
*/
|
@Override
|
public String downloadFileByOid(String fileOids) throws VciBaseException {
|
VciBaseUtil.alertNotNull(fileOids,"文件主键");
|
List<String> fileOidList = VciBaseUtil.str2List(fileOids);
|
String tempFilePath = null;
|
if(fileOidList.size() == 1){
|
String fileOid = fileOidList.get(0);
|
|
VciFileObjectVO vciFileObjectVO = vciFileObjectServiceI.getObjectByOid(fileOid);
|
|
VciFileVolumeVO vciFileVolumeVO = null;
|
if(StringUtils.isNotBlank(vciFileObjectVO.getPkFileVolume())){
|
vciFileVolumeVO = vciFileVolumeServiceI.getObjectByOid(vciFileObjectVO.getPkFileVolume());
|
}else{
|
vciFileVolumeVO = vciFileVolumeServiceI.getObjectById(vciFileObjectVO.getFilePath().split(":")[0]);
|
}
|
tempFilePath = downloadFile(vciFileObjectVO,vciFileVolumeVO,LocalFileUtil.getDefaultTempFolder());
|
//其他的协议的后续补充
|
}
|
if(fileOidList.size()>1){
|
tempFilePath = downloadFileByOids(fileOidList);
|
}
|
|
return tempFilePath;
|
}
|
|
/**
|
* 执行下载
|
* @param vciFileObjectVO 文件的对象
|
* @param vciFileVolumeVO 卷的对象
|
* @return 下载后的地址
|
*/
|
private String downloadFile(VciFileObjectVO vciFileObjectVO,VciFileVolumeVO vciFileVolumeVO,String tempFolder){
|
String fileName = vciFileObjectVO.getName()+"."+vciFileObjectVO.getFileExtension();
|
String tempDir = StringUtils.isNotBlank(tempFolder)?tempFolder:LocalFileUtil.getDefaultTempFolder();
|
String tempFilePath = tempDir+File.separator+vciFileObjectVO.getName()+"."+vciFileObjectVO.getFileExtension();
|
//本地协议
|
File tempFile = new File(tempFilePath);
|
File tempDirFile = tempFile.getParentFile();
|
if(!tempDirFile.exists()){
|
tempDirFile.mkdirs();
|
}
|
if(!tempFile.exists()){
|
try {
|
tempFile.createNewFile();
|
} catch (IOException e) {
|
throw new VciBaseException("在临时文件夹下创建临时文件出错",new String[0],e);
|
}
|
}
|
if(vciFileVolumeVO.getTransProtocol().equals(VciFileTransProtocolEnum.LOCAL.getValue())){
|
try{
|
String filePath = vciFileVolumeVO.getVolumePath()+File.separator+vciFileObjectVO.getFilePath();
|
File file = new File(filePath);
|
if(!file.exists()){
|
throw new VciBaseException(FILE_NOT_FOUND,new String[]{""});
|
}
|
LocalFileUtil.copyFile(file,tempFile);
|
}catch (Exception e){
|
throw new VciBaseException(DOWNLOAD_FAIL, new String[]{e.getMessage()});
|
}
|
}else if(VciFileTransProtocolEnum.CORBA.getValue().equalsIgnoreCase(vciFileVolumeVO.getTransProtocol())){
|
String volumeName = vciFileVolumeVO.getName();
|
VolumeServicePrx volumnCorbaService = platformClientUtil.getVolumeService(volumeName);
|
if(volumnCorbaService == null){
|
throw new VciBaseException("没有获取到卷服务");
|
}
|
//平台2020版本此处修改了,卷的文件夹是由卷服务来控制
|
String serverPath = vciFileObjectVO.getFilePath();
|
long fileSize = 0;
|
try {
|
fileSize = volumnCorbaService.getFileSize(serverPath);
|
} catch (PLException vciError) {
|
throw new VciBaseException("没有在卷服务{}里获取到文件{}的大小",new String[]{volumeName,fileName},vciError);
|
}
|
try {
|
FileOutputStream destFileOs = new FileOutputStream(tempFilePath);
|
long blockSize = webProperties.getBlockLength()*1024;
|
if(blockSize> Integer.MAX_VALUE){
|
blockSize = Integer.MAX_VALUE;
|
}
|
long temp = 0;
|
while (fileSize - temp > blockSize) {
|
destFileOs.write(volumnCorbaService.sendFile(serverPath, temp));
|
temp += blockSize;
|
}
|
destFileOs.write(volumnCorbaService.sendFile(serverPath, temp));
|
destFileOs.flush();
|
destFileOs.close();
|
} catch (FileNotFoundException e) {
|
throw new VciBaseException("要写入的文件没有找到",new String[]{tempFilePath},e);
|
} catch (IOException e) {
|
throw new VciBaseException("写入文件出错" + e.getMessage(),new String[]{tempFilePath},e);
|
} catch (PLException e){
|
// throw new VciBaseException("卷服务传输文件时出现了错误" + e.error_code,e.error_message,e);
|
}catch (Exception e){
|
throw new VciBaseException("卷服务传输文件时出现了错误" + e.getMessage(),new String[0],e);
|
}
|
}
|
return tempFilePath;
|
}
|
|
/**
|
* 根据主键批量下载文件,会下载到默认的临时文件下
|
* @param fileOids 文件的主键集合
|
* @return 文件所在本地的压缩包的全路径
|
* @throws VciBaseException 参数为空或者文件出错的时候会抛出异常
|
*/
|
public String downloadFileByOids(Collection<String> fileOids) throws VciBaseException {
|
List<VciFileObjectDO> vciFileObjectDOS = vciFileObjectMapper.selectByPrimaryKeyCollection(fileOids);
|
|
String localFolder = LocalFileUtil.getDefaultTempFolder();
|
String zipFileName = vciFileObjectDOS.iterator().next().getId()+"等多文件.zip";
|
|
String zipFile =localFolder + File.separator+zipFileName;
|
|
File[] tempFiles = new File[vciFileObjectDOS.size()];
|
int i = 0;
|
|
for(VciFileObjectDO vciFileObjectDO : vciFileObjectDOS){
|
VciFileVolumeVO vciFileVolumeVO = null;
|
if(StringUtils.isBlank(vciFileObjectDO.getPkFileVolume()) && StringUtils.isNotBlank(vciFileObjectDO.getFilePath())){
|
vciFileVolumeVO = vciFileVolumeServiceI.getObjectById(vciFileObjectDO.getFilePath().split(":")[0]);
|
}else {
|
vciFileVolumeVO = vciFileVolumeServiceI.getObjectByOid(vciFileObjectDO.getPkFileVolume());
|
}
|
String tempFilePath = downloadFile(vciFileObjectServiceI.vciFileObjectDO2VO(vciFileObjectDO),vciFileVolumeVO,localFolder);
|
tempFiles[i] = new File(tempFilePath);
|
i++;
|
}
|
|
zipUtil.addFileToZip(tempFiles, zipFile);
|
|
//文件添加到压缩包后,将临时文件删除。
|
for(File file : tempFiles){
|
file.delete();
|
file.getParentFile().delete();
|
}
|
|
return zipFile;
|
}
|
|
@Override
|
public String downloadFileByOid(String clientPath, String fileOid) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public Map<String, String> batchDownloadFileByOids(Collection<String> fileOidCollection) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public Map<String, String> batchDownloadFileByOids(String clientPath, Collection<String> fileOidCollection) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public Map<String, String> batchDownloadFileByOids(String clientPath, Collection<String> fileOidCollection, boolean sameFileUseOidFolder) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public String downloadFileByFileObject(VciFileObjectVO fileObjectVO) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public String downloadFileByFileObject(String clientPath, VciFileObjectVO fileObjectVO) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public Map<String, String> batchDownloadFileByFileObject(Collection<VciFileObjectVO> fileObjectVOCollection) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public Map<String, String> batchDownloadFileByFileObject(String clientPath, Collection<VciFileObjectVO> fileObjectVOCollection) throws VciBaseException {
|
return null;
|
}
|
|
@Override
|
public void downloadZipFileByOids(String zipFileName, String fileOid) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipFileByOids(ZipFile zipFile, String fileOid) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipStreamByOids(ZipOutputStream zipOutputStream, String fileOid) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipFileByOids(String zipFileName, Collection<String> fileOidCollection) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipFileByOids(ZipFile zipFile, Collection<String> fileOidCollection) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipStreamByOids(ZipOutputStream zipOutputStream, Collection<String> fileOidCollection) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipFileByOids(ZipFile zipFile, Collection<String> fileOidCollection, boolean sameFileUseOidFolder) throws VciBaseException {
|
|
}
|
|
@Override
|
public void downloadZipStreamByOids(ZipOutputStream zipOutputStream, Collection<String> fileOidCollection, boolean sameFileUseOidFolder) throws VciBaseException {
|
|
}
|
|
/**
|
* 分片下载
|
* @param fileOid 文件主键
|
* @param offSet 偏移量
|
* @return 数据
|
* @throws VciBaseException 下载出错的时候会抛出异常
|
*/
|
@Override
|
public BaseResult<byte[]> sectionDownloadByFileOid(String fileOid, long offSet) throws VciBaseException {
|
BaseResult<byte[]> baseResult = new BaseResult();
|
VciFileObjectVO vciFileObjectVO = vciFileObjectServiceI.getObjectByOid(fileOid);
|
|
VciFileVolumeVO vciFileVolumeVO = null;
|
if(StringUtils.isBlank(vciFileObjectVO.getPkFileVolume()) && StringUtils.isNotBlank(vciFileObjectVO.getFilePath())){
|
vciFileVolumeVO = vciFileVolumeServiceI.getObjectById(vciFileObjectVO.getFilePath().split(":")[0]);
|
}else {
|
vciFileVolumeVO = vciFileVolumeServiceI.getObjectByOid(vciFileObjectVO.getPkFileVolume());
|
}
|
String fileName = vciFileObjectVO.getName()+"."+vciFileObjectVO.getFileExtension();
|
//本地协议
|
if(vciFileVolumeVO.getTransProtocol().equals(VciFileTransProtocolEnum.LOCAL.getValue())){
|
String sourceFilePath = vciFileVolumeVO.getVolumePath()+File.separator+vciFileObjectVO.getFilePath();
|
File sourceFile = new File(sourceFilePath);
|
if(!sourceFile.exists()){
|
throw new VciBaseException(FILE_NOT_FOUND,new String[]{""});
|
}
|
|
long fileSize = sourceFile.length();
|
RandomAccessFile destfile = null;
|
try{
|
byte[] buffer ;
|
if(offSet<(fileSize- VciFileServerClientUtil.BLOCKSIZE)){
|
buffer = new byte[VciFileServerClientUtil.BLOCKSIZE];
|
}else{
|
buffer = new byte[(int) (fileSize-offSet)];
|
}
|
destfile = new RandomAccessFile(sourceFile, "rw");
|
destfile.seek(offSet);
|
destfile.read(buffer);
|
|
baseResult.setSuccess(true);
|
baseResult.setMsg(DOWNLOAD_SUCCESS);
|
baseResult.setObj(buffer);
|
} catch (Exception e){
|
throw new VciBaseException(FILE_READ_FAIL,new String[]{vciFileObjectVO.getName()});
|
}finally {
|
if(destfile != null){
|
try {
|
destfile.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
}else if(VciFileTransProtocolEnum.CORBA.getValue().equalsIgnoreCase(vciFileVolumeVO.getTransProtocol())){
|
String volumeName = vciFileVolumeVO.getName();
|
VolumeServicePrx volumnCorbaService = platformClientUtil.getVolumeService(volumeName);
|
if(volumnCorbaService == null){
|
throw new VciBaseException("没有获取到卷服务");
|
}
|
String serverPath = vciFileVolumeVO.getVolumePath() + File.separator + vciFileObjectVO.getFilePath().replace(volumeName+":","");
|
long fileSize = 0;
|
try {
|
fileSize = volumnCorbaService.getFileSize(serverPath);
|
} catch (PLException vciError) {
|
throw new VciBaseException("没有在卷服务{}里获取到文件{}的大小",new String[]{volumeName,fileName},vciError);
|
}
|
try {
|
baseResult.setSuccess(true);
|
baseResult.setMsg(DOWNLOAD_SUCCESS);
|
baseResult.setObj( volumnCorbaService.sendFile(serverPath, fileSize-offSet));
|
} catch (Exception e){
|
throw new VciBaseException(FILE_READ_FAIL,new String[]{vciFileObjectVO.getName()});
|
}
|
}
|
//其他协议的下载,后续完善
|
|
return baseResult;
|
}
|
|
/**
|
* 删除文件
|
* @param fileOidCollection 文件主键集合
|
* @return 执行结果
|
* @throws VciBaseException 删除出错的时候会抛出异常
|
*/
|
@Override
|
public BaseResult deleteFile(Collection<String> fileOidCollection) throws VciBaseException {
|
List<VciFileObjectDO> fileObjectDOList = vciFileObjectMapper.selectByPrimaryKeyCollection(fileOidCollection);
|
for(VciFileObjectDO fileObjectDO : fileObjectDOList){
|
VciFileVolumeVO fileVolumeVO = vciFileVolumeServiceI.getObjectByOid(fileObjectDO.getPkFileVolume());
|
//本地协议
|
if(fileVolumeVO.getTransProtocol().equals(VciFileTransProtocolEnum.LOCAL.getValue())){
|
String volumePath = fileVolumeVO.getVolumePath();
|
|
String filePath = volumePath+File.separator+fileObjectDO.getFilePath();
|
|
File file = new File(filePath);
|
if(file.exists()){
|
file.delete();
|
}
|
|
File dirFile = file.getParentFile();
|
if(dirFile.listFiles().length>0){
|
//说明此目录下还有其他文件,此目录不能删除
|
}else{
|
dirFile.delete();
|
}
|
|
vciFileObjectMapper.deleteByPrimaryKey(fileObjectDO.getOid());
|
}else if(VciFileTransProtocolEnum.CORBA.getValue().equalsIgnoreCase(fileVolumeVO.getTransProtocol())){
|
//暂时不删除文件
|
vciFileObjectMapper.deleteByPrimaryKey(fileObjectDO.getOid());
|
}
|
|
//其他协议,后续完善
|
|
}
|
|
return BaseResult.success(DELETE_SUCCESS);
|
}
|
|
/**
|
* 使用卷服务上的文件路径来下载
|
*
|
* @param filePath 文件的路径
|
* @return 下载后的地址
|
* @throws VciBaseException 下载出错会抛出异常
|
*/
|
@Override
|
public String downloadFileByPath( String filePath) throws VciBaseException {
|
VciBaseUtil.alertNotNull(filePath,"文件路径");
|
String volumeId = "";
|
if (filePath.contains(":")) {
|
volumeId = filePath.split(":")[0];
|
filePath = filePath.split(":")[1];
|
} else {
|
throw new VciBaseException("文件的路径格式不正确,需要xxx:yyyy");
|
}
|
VciFileVolumeVO vciFileVolumeVO = vciFileVolumeServiceI.getObjectById(volumeId);
|
|
if(filePath.contains(".")){
|
//直接传递的完整的路径
|
String tempFilePath = LocalFileUtil.getDefaultTempFolder() + File.separator ;
|
String fileName = "";
|
if(filePath.contains(File.separator)){
|
fileName = filePath.substring(filePath.lastIndexOf(File.separator)+1);
|
}else{
|
if(filePath.contains("/")){
|
fileName= filePath.substring(filePath.lastIndexOf("/")+1);
|
}else{
|
fileName = filePath.replace(volumeId+":","");
|
}
|
}
|
tempFilePath = tempFilePath+fileName;
|
File tempFile = new File(tempFilePath);
|
File tempDirFile = tempFile.getParentFile();
|
if(!tempDirFile.exists()){
|
tempDirFile.mkdirs();
|
}
|
if(!tempFile.exists()){
|
try {
|
tempFile.createNewFile();
|
} catch (IOException e) {
|
throw new VciBaseException("在临时文件夹中创建临时文件出错",new String[0],e);
|
}
|
}
|
if(vciFileVolumeVO.getTransProtocol().equals(VciFileTransProtocolEnum.LOCAL.getValue())){
|
try{
|
File file = new File(filePath.replace(volumeId + ":",vciFileVolumeVO.getVolumePath()));
|
if(!file.exists()){
|
throw new VciBaseException(FILE_NOT_FOUND,new String[]{""});
|
}
|
|
LocalFileUtil.copyFile(file,tempFile);
|
}catch (Exception e){
|
throw new VciBaseException(DOWNLOAD_FAIL, new String[]{e.getMessage()});
|
}
|
}else if(VciFileTransProtocolEnum.CORBA.getValue().equalsIgnoreCase(vciFileVolumeVO.getTransProtocol())){
|
String volumeName = vciFileVolumeVO.getName();
|
VolumeServicePrx volumnCorbaService = platformClientUtil.getVolumeService(volumeName);
|
if(volumnCorbaService == null){
|
throw new VciBaseException("没有获取到卷服务");
|
}
|
//平台2020版本此处修改了,卷的文件夹是由卷服务来控制
|
String serverPath = volumeId+":" + filePath;
|
long fileSize = 0;
|
try {
|
fileSize = volumnCorbaService.getFileSize(serverPath);
|
} catch (PLException vciError) {
|
throw new VciBaseException("没有在卷服务{}里获取到文件{}的大小",new String[]{volumeName,fileName},vciError);
|
}
|
try {
|
FileOutputStream destFileOs = new FileOutputStream(tempFilePath);
|
long blockSize = webProperties.getBlockLength()*1024;
|
if(blockSize> Integer.MAX_VALUE){
|
blockSize = Integer.MAX_VALUE;
|
}
|
long temp = 0;
|
while (fileSize - temp > blockSize) {
|
destFileOs.write(volumnCorbaService.sendFile(serverPath, temp));
|
temp += blockSize;
|
}
|
destFileOs.write(volumnCorbaService.sendFile(serverPath, temp));
|
destFileOs.flush();
|
destFileOs.close();
|
} catch (FileNotFoundException e) {
|
throw new VciBaseException("要写入的文件没有找到",new String[]{tempFilePath},e);
|
} catch (IOException e) {
|
throw new VciBaseException("写入文件出错" + e.getMessage(),new String[]{tempFilePath},e);
|
} catch (PLException e){
|
// throw new VciBaseException("卷服务传输文件时出现了错误" + e.error_code,e.error_message,e);
|
}catch (Exception e){
|
throw new VciBaseException("卷服务传输文件时出现了错误" + e.getMessage(),new String[0],e);
|
}
|
}
|
return tempFilePath;
|
}else {
|
VciQueryWrapperForDO queryWrapperForDO = new VciQueryWrapperForDO(null, VciFileObjectDO.class);
|
queryWrapperForDO.eq("filepath", volumeId + ":" + filePath);
|
List<VciFileObjectDO> fileObjectDOS = vciFileObjectMapper.selectByWrapper(queryWrapperForDO);
|
if (CollectionUtils.isEmpty(fileObjectDOS)) {
|
throw new VciBaseException("没有找到这个路径下的文件信息");
|
}
|
return downloadFile(vciFileObjectServiceI.vciFileObjectDO2VO(fileObjectDOS.get(0)), vciFileVolumeVO,null);
|
}
|
}
|
}
|