package com.vci.server.volume;
|
|
import java.io.BufferedInputStream;
|
import java.io.BufferedOutputStream;
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.FileOutputStream;
|
import java.io.RandomAccessFile;
|
import java.io.UnsupportedEncodingException;
|
import java.math.BigInteger;
|
import java.net.InetAddress;
|
import java.net.UnknownHostException;
|
import java.security.MessageDigest;
|
import java.util.ArrayList;
|
import java.util.HashMap;
|
import java.util.Hashtable;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.concurrent.Callable;
|
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.Executors;
|
import java.util.concurrent.Future;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import com.vci.common.ServiceNames;
|
import com.vci.corba.common.VCIError;
|
import com.vci.corba.volume.VolumeService;
|
import com.vci.corba.volume.data.FileInfo;
|
import com.vci.corba.framework.data.PvolumeInfo;
|
import com.vci.corba.volume.data.VolumeUseInfo;
|
import com.vci.server.BaseService;
|
import com.vci.server.base.utility.ServerServiceProvider;
|
import com.vci.server.cache.OMCacheProvider;
|
import com.vci.server.cache.VolumeCacheProvider;
|
import com.vci.server.volume.delegate.FileControl;
|
import com.vci.server.volume.delegate.RC4;
|
import com.vci.server.volume.objects.VolumeFileUploadStatusInfo;
|
import com.vci.server.volume.uitls.EncryFileUtil;
|
import com.vci.server.volume.uitls.VolumeProperties;
|
import com.vci.server.volume.uitls.VolumeWithLog4j;
|
import com.zeroc.Ice.Current;
|
|
/**
|
* <p>Title: </p>
|
* <p>Description: </p>
|
* <p>Copyright: Copyright (c) 2011</p>
|
* <p>Company: VCI</p>
|
* @author Administrator
|
* @time 2011-7-3
|
* @version 1.0
|
*/
|
public class VolumeServiceImpl extends BaseService implements VolumeService{
|
|
int blockLength = 0;
|
int intBackUpCount = 0;
|
Boolean isFileEncry = false;
|
Boolean isReadOnly = false;
|
FileControl fileControl = new FileControl();
|
|
String fileKey = "vci@2008";
|
|
//PvolumeDelegate _volDelegate = new PvolumeDelegate();
|
|
Hashtable<String, PvolumeInfo> mapVolumn = new Hashtable<String, PvolumeInfo>();
|
Hashtable<String, RandomAccessFile> hashtable = new Hashtable<String, RandomAccessFile>();
|
|
public VolumeServiceImpl() {
|
try {
|
blockLength = VolumeProperties.blockLength() * 1024;
|
intBackUpCount = VolumeProperties.historyCopyCount();
|
|
isFileEncry = VolumeProperties.isFileEncry();
|
|
isReadOnly = VolumeProperties.isReadOnly();
|
|
} catch (Exception e) {
|
//e.printStackTrace();
|
VolumeWithLog4j.logger.error(e);
|
}
|
}
|
|
@Override
|
public String getServiceName() {
|
return VolumeProperties.VolumeServiceName();
|
}
|
|
|
/**
|
* 获取文件的更改时间
|
*/
|
public long getFileModifiedTime(String fileName, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
long modifiedTime = 0;
|
try {
|
File currentFile = new File(fileName);
|
if (!currentFile.exists()) {
|
throw new VCIError("710001", new String[]{fileName});
|
}
|
modifiedTime = currentFile.lastModified();
|
} catch (Exception g) {
|
//g.printStackTrace();
|
VolumeWithLog4j.logger.error("710002", g);
|
throw new VCIError("710002", new String[0]);
|
}
|
return modifiedTime;
|
}
|
|
/**
|
* 获取文件大小
|
*/
|
public long getFileSize(String fileName, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
long size = -1;
|
try {
|
File file = new File(fileName);
|
if (!file.exists()) {
|
throw new VCIError("710001", new String[0]);//服务器端文件不存在!
|
}
|
boolean isEncry = EncryFileUtil.isEncryFile(file);
|
|
size = file.length() - (isEncry ? EncryFileUtil.ENCRYHEADERSIZE : 0);
|
} catch (Exception g) {
|
//g.printStackTrace();
|
VolumeWithLog4j.logger.error("710003", g);
|
throw new VCIError("710003", new String[1]);//获取服务器端文件大小出错,请重新获取!
|
}
|
return size;
|
}
|
|
private Map<String, VolumeFileUploadStatusInfo> uploadStateInfoMap = new ConcurrentHashMap<String, VolumeFileUploadStatusInfo>();
|
/**
|
* receive one subsection of file from client everytime,and save them into
|
* a temporary file. When finished, save the file name into the rigth one.
|
*/
|
public boolean receiveFile(String fileName, byte[] data, long pointoffile,
|
long modifiedtime, long filesize, Current current) throws VCIError {
|
|
if (isReadOnly)
|
throw new VCIError("710000", new String[0]);//("服务器端文件已锁定,请稍后再试!");
|
|
fileName = hanlderOS(fileName);
|
String TempProfix = getTempFileSufixx(); //临时文件后缀
|
File newfile = new File(fileName + TempProfix);
|
if (pointoffile == 0 && !fileControl.lockWrite(fileName + TempProfix)) {
|
throw new VCIError("710004", new String[0]);//("服务器端文件已锁定,请稍后再试!");
|
}
|
|
boolean islast = false;
|
boolean alreadExistInMap = uploadStateInfoMap.containsKey(fileName);
|
VolumeFileUploadStatusInfo uploadInfo = new VolumeFileUploadStatusInfo();
|
if(alreadExistInMap){
|
uploadInfo = uploadStateInfoMap.get(fileName);
|
} else {
|
uploadInfo.setClientFileSize(filesize);
|
uploadInfo.setDestFileFullName(fileName);
|
uploadInfo.setBeginTransferTime(System.currentTimeMillis());
|
}
|
|
RandomAccessFile destfile = null;
|
try {
|
if (pointoffile == 0) { //开始传新的文件
|
newfile.mkdirs();
|
newfile.delete();
|
destfile = new RandomAccessFile(newfile.getPath(), "rw");
|
// 如果启用文件加密,则需要在文件开始写入加密标识文件头
|
if (this.isFileEncry) {
|
byte[] encryHeader = EncryFileUtil.getEncryHeader(fileName);
|
|
if (encryHeader != null && encryHeader.length > 0) {
|
destfile.write(encryHeader, 0, encryHeader.length);
|
}
|
}
|
hashtable.put(fileName, destfile);
|
}
|
destfile = ( (RandomAccessFile) hashtable.get(fileName));
|
data = encryByte(data);
|
|
if ( (filesize - pointoffile) > blockLength) {
|
destfile.write(data, 0, blockLength);
|
|
uploadInfo.setTransferCount(uploadInfo.getTransferCount() + 1);
|
uploadInfo.setEndTransferTime(System.currentTimeMillis());
|
uploadInfo.setSpanTransfer(uploadInfo.getEndTransferTime() - uploadInfo.getBeginTransferTime());
|
uploadStateInfoMap.put(fileName, uploadInfo);
|
} else {
|
destfile.write(data, 0, (int) (filesize - pointoffile));
|
destfile.close();
|
destfile = null;
|
hashtable.remove(fileName);
|
fileControl.lockWrite(fileName);
|
File file0 = new File(fileName);
|
|
handleDataFileHistoryCopy(fileName);
|
|
newfile.renameTo(file0);
|
newfile.setLastModified(modifiedtime);
|
fileControl.unlockWrite(fileName);
|
fileControl.unlockWrite(fileName + TempProfix);
|
|
uploadInfo.setTransferCount(uploadInfo.getTransferCount() + 1);
|
uploadInfo.setEndTransferTime(System.currentTimeMillis());
|
uploadInfo.setSpanTransfer(uploadInfo.getEndTransferTime() - uploadInfo.getBeginTransferTime());
|
islast = true;
|
VolumeWithLog4j.logger.info(uploadInfo.toString());
|
}
|
} catch (Exception eRe) {
|
VolumeWithLog4j.logger.error(fileName, eRe);
|
|
//System.out.println("FileTranImpl::ReceiveFile:" + fileName + TempProfix + eRe.getMessage());
|
try {
|
fileControl.unlockWrite(fileName + TempProfix);
|
if (destfile != null) {
|
destfile.close();
|
destfile = null;
|
}
|
} catch (Exception dd) {
|
VolumeWithLog4j.logger.error(fileName, dd);
|
}
|
try {
|
hashtable.remove(fileName);
|
} catch (Exception ee) {
|
VolumeWithLog4j.logger.error(fileName, ee);
|
}
|
fileControl.unlockWrite(fileName);
|
|
//eRe.printStackTrace();
|
VolumeWithLog4j.logger.error("710005", eRe);
|
throw new VCIError("710005", new String[0]);//("服务器端接收文件出错!" + eRe.getStackTrace());
|
} finally{
|
if(islast && alreadExistInMap){
|
uploadStateInfoMap.remove(fileName);
|
}
|
}
|
return true;
|
}
|
|
/**
|
* 返回临时文件名后缀
|
* @return
|
*/
|
private String getTempFileSufixx(){
|
return "$transfer"; //临时文件后缀
|
}
|
/**
|
* 校验上传到卷服务的文件是否完整(完成)
|
* @param destFileFullPath 远程文件完整路径
|
* @param clientFileSize 客户端文件大小
|
* @param clientFileMD5 客户端文件MD5值
|
* @param otherParams 其它保留参数
|
* @return
|
* @throws VCIError
|
*/
|
public boolean verifyFileUploadSuccess(String destFileFullPath,
|
long clientFileSize, String clientFileMD5, String[] otherParams, Current current) throws VCIError{
|
boolean res = true;
|
/**
|
* 基础逻辑:
|
* 1、检验destFileFullPath是否存在,如果存在校验clientFileSize是否一致,一致代表成功,不一致代表失败;
|
* 2、destFileFullPath不存在时,校验destFileFullPath+$transfer是否存在,如果存在校验clientFileSize和destFileFullPath+$transfer的大小是否一致,如果一致将fileName+$transfer重命名为fileName,返回成功,否则失败
|
*/
|
|
destFileFullPath = hanlderOS(destFileFullPath);
|
|
//System.out.println("========校验文件 [" + destFileFullPath + "]开始====================");
|
VolumeWithLog4j.logger.debug("校验文件:" + destFileFullPath);
|
|
String sInfo = "";
|
|
File destFile = new File(destFileFullPath);
|
if(destFile.exists()){
|
// destFileFullPath 文件存在只判断大小是否匹配
|
if (this.isFileEncry)
|
res = (clientFileSize == (destFile.length() - 13));
|
else
|
res = clientFileSize == destFile.length();
|
|
//System.out.println("====校验文件 [" + destFileFullPath + "]结果:" + res + "\n客户端大小:" + clientFileSize + "; 服务端大小:" + destFile.length());
|
sInfo = "校验文件 [" + destFileFullPath + "] 结果:" + res + "; 客户端大小:" + clientFileSize + "; 服务端大小:" + destFile.length();
|
VolumeWithLog4j.logger.debug(sInfo);
|
} else {
|
String TempProfix = getTempFileSufixx(); //临时文件后缀
|
String tempFileFullPath = destFileFullPath + TempProfix;
|
File tempFile = new File(tempFileFullPath);
|
if(tempFile.exists()){
|
// 临时文件存在
|
// 判断临时文件大小与clientFileSize是否匹配
|
boolean sizeEqual = clientFileSize == tempFile.length();
|
if(sizeEqual){
|
// 大小相同
|
res = true;
|
// 重命名
|
tempFile.renameTo(destFile);
|
} else {
|
res = false;
|
}
|
|
//System.out.println("====校验文件 [" + tempFileFullPath + "]结果:" + res + "\n客户端大小:" + clientFileSize + "; 服务端大小:" + tempFile.length());
|
sInfo = "校验文件 [" + tempFileFullPath + "]结果:" + res + "; 客户端大小:" + clientFileSize + "; 服务端大小:" + tempFile.length();
|
VolumeWithLog4j.logger.debug(sInfo);
|
|
} else {
|
//System.out.println("====校验文件 [" + tempFileFullPath + "] 失败,临时文件不存在===");
|
sInfo = "校验文件 [" + tempFileFullPath + "] 失败,临时文件不存在";
|
VolumeWithLog4j.logger.debug(sInfo);
|
|
res = false;
|
}
|
}
|
|
//System.out.println("========校验文件 [" + destFileFullPath + "] 结束====================:" + res);
|
sInfo = "校验文件 [" + destFileFullPath + "] 结束";
|
VolumeWithLog4j.logger.debug(sInfo);
|
|
return res;
|
}
|
|
private byte[] encryByte(byte[] file) {
|
if (isFileEncry) {// != null && isFileEncry.equalsIgnoreCase("true")) {
|
return RC4.encry_RC4_byte(file, fileKey);
|
} else {
|
return file;
|
}
|
}
|
|
private byte[] decryByte(byte[] file) {
|
if (isFileEncry) {// != null && isFileEncry.equalsIgnoreCase("true")) {
|
return RC4.encry_RC4_byte(file, fileKey);
|
} else {
|
return file;
|
}
|
}
|
|
/**
|
* deal with the history copy of current file. It has the max number of copies,
|
* the names of copies are **.bak0, **.bak1, **.bak2..., and **.bak0 is the latest one.
|
* ** is the name of current file.
|
*
|
* @param sFileName
|
* @return
|
* @throws VCIError
|
*/
|
private boolean handleDataFileHistoryCopy(String sFileName) throws VCIError {
|
//mod by wcx@20201105 子方法都做了处理,重复处理有异常
|
// sFileName = hanlderOS(sFileName);
|
boolean isSuccess = false;
|
try {
|
int currentHistoryCopyCount = (int) getDataFileHistoryCopyCount(sFileName);
|
if (currentHistoryCopyCount < 1) {
|
return true;
|
}
|
if (currentHistoryCopyCount <= intBackUpCount) {
|
for (int i = currentHistoryCopyCount - 2; i >=0 ; i--) {
|
ChangeFileNameEx(sFileName + ".bak" + i, sFileName + ".bak" + (i + 1));
|
}
|
ChangeFileNameEx(sFileName, sFileName + ".bak0");
|
} else {
|
for (int i = intBackUpCount - 1; i < currentHistoryCopyCount - 1; i++) {
|
deleteFileEx(sFileName + ".bak" + i);
|
}
|
for (int i = intBackUpCount - 2; i >= 0; i--) {
|
ChangeFileNameEx(sFileName + ".bak" + i, sFileName + ".bak" + (i + 1));
|
}
|
ChangeFileNameEx(sFileName, sFileName + ".bak0");
|
}
|
} catch (Exception e) {
|
//e.printStackTrace();
|
VolumeWithLog4j.logger.error("710006", e);
|
throw new VCIError("710006", new String[0]);
|
}
|
return isSuccess;
|
}
|
|
/**
|
* get the copy count of current file.
|
*
|
* @param sFileName
|
* @return
|
* @throws VCIError
|
*/
|
private long getDataFileHistoryCopyCount(java.lang.String sFileName) throws VCIError {
|
// sFileName = hanlderOS(sFileName);
|
int iHistoryCopyCount = 0;
|
try {
|
String sFileNameTemp = sFileName;
|
File sFileTemp = new File(sFileNameTemp);
|
if (sFileTemp.exists()) {
|
iHistoryCopyCount++;
|
}
|
for (int i = 0; ; i++) {
|
sFileNameTemp = sFileName + ".bak" + i;
|
sFileTemp = new File(sFileNameTemp);
|
if (sFileTemp.exists()) {
|
iHistoryCopyCount++;
|
} else {
|
break;
|
}
|
}
|
} catch (Exception ex) {
|
VolumeWithLog4j.logger.error("710007", ex);
|
throw new VCIError("710007", new String[0]);//("获取数据文件历史备份数出错!");
|
}
|
return iHistoryCopyCount;
|
}
|
|
/**
|
* 更改文件名称
|
*/
|
public boolean ChangeFileName(String resName, String desName, Current current) throws VCIError {
|
resName = hanlderOS(resName);
|
desName = hanlderOS(desName);
|
return ChangeFileNameEx(resName, desName);
|
}
|
|
/**
|
* 更改文件名称,内部方法
|
*/
|
private boolean ChangeFileNameEx(String resName, String desName) throws VCIError {
|
//resName = hanlderOS(resName);
|
//desName = hanlderOS(desName);
|
try {
|
File res = new File(resName);
|
if (!res.exists()) {
|
throw new VCIError("710001", new String[0]);//("原文件不存在,修改文件名称错误!");
|
}
|
File des = new File(desName);
|
if (des.exists()) {
|
throw new VCIError("710008", new String[0]);//("目标文件已经存在,修改文件名称错误!");
|
}
|
res.renameTo(des);
|
return true;
|
} catch (Exception g) {
|
throw new VCIError("710009", new String[0]);// throw new com.tji.kpdm.volume.PdmError (102,"更改文件名出错!");
|
}
|
}
|
|
/**
|
* 删除文件
|
*/
|
public boolean deleteFile(String fileName, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
|
return deleteFileEx(fileName);
|
}
|
|
|
/**
|
* 删除文件,内部方法
|
*/
|
private boolean deleteFileEx(String fileName) throws VCIError {
|
//fileName = hanlderOS(fileName);
|
try {
|
File filedelete = new File(fileName);
|
|
if (!filedelete.exists()) {
|
return true;
|
}
|
filedelete.delete();
|
return true;
|
}
|
catch (Exception g) {
|
g.printStackTrace();
|
throw new VCIError("710010", new String[0]);// 删除文件出错,请重新删除!
|
}
|
}
|
|
/**
|
* 复制文件
|
* @param fromFileName,原文件全路径
|
* @param copyFileName,复制后文件全路径
|
* @return
|
* @throws VCIError
|
*/
|
public boolean copyFile(String fromFileName, String copyFileName, Current current) throws VCIError {
|
fromFileName = hanlderOS(fromFileName);
|
copyFileName = hanlderOS(copyFileName);
|
BufferedInputStream inbuff = null;
|
BufferedOutputStream outbuff = null;
|
try {
|
File res = new File(fromFileName);
|
if (!res.exists()) {
|
throw new VCIError("710001", new String[0]);//("原文件不存在,修改文件名称错误!");
|
}
|
File des = new File(copyFileName);
|
if (des.exists()) {
|
throw new VCIError("710008", new String[0]);//("目标文件已经存在,修改文件名称错误!");
|
}
|
if (!des.exists()) {
|
des.mkdirs();
|
des.delete();
|
}
|
//新建文件输入流
|
inbuff = new BufferedInputStream(new FileInputStream(res));
|
//新建文件输出流
|
outbuff = new BufferedOutputStream(new FileOutputStream(des));
|
//缓冲数组
|
byte[] b = new byte[1024 * 5];
|
int len;
|
while ((len = inbuff.read(b)) != -1) {
|
outbuff.write(b, 0, len);
|
}
|
outbuff.flush();
|
return true;
|
} catch (Exception g) {
|
throw new VCIError("710023", new String[0]);// 复制文件出错
|
} finally {
|
try {
|
if (inbuff != null) {
|
inbuff.close();
|
}
|
if (outbuff != null) {
|
outbuff.close();
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
|
private String hanlderOS(String strFileName) {
|
String strNewFileName = strFileName;
|
|
// 将服务器文件路径转换为实际路径,替换路径前的“<卷>:”为卷的实际路径
|
int index = strNewFileName.indexOf(":");
|
if (index > 0)
|
{
|
String volumn = strNewFileName.substring(0, index);
|
|
try
|
{
|
PvolumeInfo pv = getVolumnInfo(volumn);
|
if (pv != null && !StringUtils.isEmpty(pv.id))
|
{
|
String path = pv.path;
|
if (path.endsWith("\\") || path.endsWith("/"))
|
path = path.substring(0, path.length() - 1);
|
|
strNewFileName = strNewFileName.replace(volumn + ":", path);
|
}
|
}
|
catch (VCIError re) {
|
VolumeWithLog4j.logger.error(strFileName, re);
|
}
|
}
|
|
String osStr = System.getProperty("os.name");
|
if ( !osStr.startsWith("Win") )
|
{
|
//Unix
|
strNewFileName = strNewFileName.replace('\\','/');
|
strNewFileName = strNewFileName.replace("//", "/");
|
}
|
else if ( osStr.startsWith("Win") )
|
{
|
//Win
|
strNewFileName = strNewFileName.replace('/','\\');
|
strNewFileName = strNewFileName.replace("\\\\", "\\");
|
}
|
|
return strNewFileName;
|
}
|
|
public long getCurrrentTimeMillions(Current current) {
|
return System.currentTimeMillis();
|
}
|
|
public boolean createDirectory(String historyDirectory, String directoryName, Current current) throws VCIError {
|
if (historyDirectory.equals(directoryName)) {
|
return true;
|
}
|
directoryName = hanlderOS(directoryName);
|
historyDirectory = hanlderOS(historyDirectory);
|
try {
|
if(!"".equalsIgnoreCase(historyDirectory)){
|
File formerFile = new File(historyDirectory);
|
String[] tempList = formerFile.list();
|
if(tempList.length != 0){
|
throw new VCIError("710011", new String[0]);
|
}
|
}
|
|
File filedir = new File(directoryName);
|
if (!filedir.exists()) {
|
filedir.mkdirs();
|
}
|
return true;
|
} catch (VCIError re) {
|
throw re;
|
} catch (Exception e) {
|
throw new VCIError("710012", new String[0]);//创建目录失败。
|
}
|
}
|
|
/**
|
* delete current file and its copies.
|
*
|
* @param sFileName
|
* @return
|
* @throws VCIError
|
*/
|
public boolean deleteAllFiles(String[] sFileNames, Current current) throws VCIError {
|
boolean isSuccess = true;
|
int length=sFileNames.length;
|
for(int i=0;i<length;i++){
|
sFileNames[i] = hanlderOS(sFileNames[i]);
|
try {
|
File delFile = new File(sFileNames[i]);
|
if (!delFile.exists()) {
|
throw new VCIError("710001", new String[0]);//("文件不存在!");
|
} else {
|
delFile.delete();
|
}
|
String sBackFileName = null;
|
for (int j = 0; j < intBackUpCount; j++) {
|
sBackFileName = sFileNames[i] + ".bak" + j;
|
delFile = new File(sBackFileName);
|
if (delFile.exists()) {
|
delFile.delete();
|
}
|
}
|
|
} catch (Exception g) {
|
VolumeWithLog4j.logger.error("710013", g);
|
|
isSuccess=false;
|
throw new VCIError("710013", new String[0]);//("删除数据文件及其备份错误!");
|
}
|
}
|
|
return isSuccess;
|
}
|
|
/**
|
* delete all copies of current file.
|
*
|
* @param sFileName
|
* @return
|
* @throws VCIError
|
*/
|
public boolean deleteAllBakFiles(String sFileName, Current current) throws VCIError {
|
boolean isSuccess = false;
|
sFileName = hanlderOS(sFileName);
|
try {
|
File delFile = new File(sFileName);
|
if (!delFile.exists()) {
|
throw new VCIError("710001", new String[0]);//("文件不存在!");
|
}
|
String sBackFileName = null;
|
for (int i = 0; i < intBackUpCount; i++) {
|
sBackFileName = sFileName + ".bak" + i;
|
delFile = new File(sBackFileName);
|
if (delFile.exists()) {
|
delFile.delete();
|
}
|
}
|
isSuccess = true;
|
} catch (Exception g) {
|
VolumeWithLog4j.logger.error("710014", g);
|
throw new VCIError("710014", new String[0]);//("删除数据文件备份错误!");
|
}
|
return isSuccess;
|
}
|
|
/**
|
* send a subsection of file to client everytime.
|
*
|
* @param fileName
|
* @param pointoffile
|
* @return
|
* @throws VCIError
|
*/
|
public byte[] sendFile(String fileName, long pointoffile, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
int bak = fileName.lastIndexOf(".bak");
|
boolean lockRead = false;
|
|
if (pointoffile == 0 && bak > 16) { //说明是历史版本文件
|
String nameTemp = fileName.substring(0, bak);
|
lockRead = fileControl.lockRead(nameTemp);
|
}
|
else if (pointoffile == 0) {
|
lockRead = fileControl.lockRead(fileName);
|
}
|
|
if (pointoffile == 0 && (!lockRead)) {
|
VolumeWithLog4j.logger.warn("710004, 文件被锁:" + fileName);
|
throw new VCIError("710004", new String[0]);//("服务器端文件已锁定,请稍后再试!");
|
} else {
|
File resoucefile = new File(fileName);
|
if (!resoucefile.exists()) {
|
VolumeWithLog4j.logger.warn("710001, 文件不存在:" + fileName);
|
throw new VCIError("710001", new String[0]);//服务器端文件不存在!
|
}
|
|
boolean isEncry = EncryFileUtil.isEncryFile(resoucefile);
|
if (isEncry)
|
pointoffile += EncryFileUtil.ENCRYHEADERSIZE;
|
|
byte[] read = null;
|
FileInputStream inputfile = null;
|
try {
|
inputfile = new FileInputStream(resoucefile);
|
|
inputfile.skip(pointoffile);
|
|
int len = blockLength;
|
if ((resoucefile.length() - pointoffile) <= blockLength) {
|
len = (int)(resoucefile.length() - pointoffile);
|
read = new byte[len];
|
} else {
|
read = new byte[blockLength];
|
}
|
|
inputfile.read(read, 0, len);
|
inputfile.close();
|
if ((resoucefile.length() - pointoffile) <= blockLength) {
|
fileControl.unlockRead(fileName);
|
}
|
|
long filesize = resoucefile.length();
|
StringBuffer log = new StringBuffer();
|
log.append("远程文件:" + fileName).append(",");
|
log.append("文件大小:" + filesize).append(",");
|
log.append("开始位置:" + pointoffile).append(",");
|
log.append("开始位置:" + (pointoffile + len)).append("");
|
//writeVolumeFileDownloadLog(log.toString());
|
VolumeWithLog4j.logger.debug(log.toString());
|
} catch (Exception e1) {
|
VolumeWithLog4j.logger.error("710015", e1);
|
|
try {
|
if (inputfile != null) {
|
inputfile.close();
|
}
|
} catch (Exception ex) {
|
}
|
fileControl.unlockRead(fileName);
|
throw new VCIError("710015", new String[0]);//服务器端发送文件出错!
|
}
|
|
if (isEncry) {
|
read = RC4.encry_RC4_byte(read, fileKey);
|
}
|
return read;
|
}
|
}
|
|
/**
|
* 获取单个文件的MD5值!用于比较两个文件是否完全相等
|
* @param file
|
* @return
|
*/
|
public String getFileMD5(String fileName, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
File file=new File(fileName);
|
if (!file.isFile()){
|
return null;
|
}
|
MessageDigest digest = null;
|
FileInputStream in=null;
|
byte buffer[] = new byte[1024];
|
int len;
|
try {
|
digest = MessageDigest.getInstance("MD5");
|
in = new FileInputStream(file);
|
while ((len = in.read(buffer, 0, 1024)) != -1) {
|
digest.update(buffer, 0, len);
|
}
|
in.close();
|
} catch (Exception e) {
|
VolumeWithLog4j.logger.error("710016", e);
|
throw new VCIError("710016", new String[0]);
|
}
|
BigInteger bigInt = new BigInteger(1, digest.digest());
|
return bigInt.toString(16);
|
}
|
|
/**
|
* 获取文件夹中文件的MD5值
|
* @param file
|
* @param listChild ;true递归子目录中的文件
|
* @return
|
*/
|
public Map<String, String> getDirMD5(String fileName,boolean listChild, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
File file=new File(fileName);
|
if(!file.isDirectory()){
|
return null;
|
}
|
//<filepath,md5>
|
Map<String, String> map=new HashMap<String, String>();
|
String md5;
|
File files[]=file.listFiles();
|
for(int i=0;i<files.length;i++){
|
File f=files[i];
|
String filePath=f.getPath();
|
if(f.isDirectory()&&listChild){
|
map.putAll(getDirMD5(filePath, listChild, current));
|
} else {
|
md5=getFileMD5(filePath, current);
|
if(md5!=null){
|
map.put(f.getPath(), md5);
|
}
|
}
|
}
|
return map;
|
}
|
|
public byte[][] downloadFile(String fileName, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
byte[][] bypes=null;
|
ArrayList<byte[]> arrayList=new ArrayList<byte[]>();
|
File file=new File(fileName);
|
if (!file.exists()) {
|
throw new VCIError("710001", new String[0]); //文件不存在
|
}
|
|
int pos = 0;
|
boolean isEncry = EncryFileUtil.isEncryFile(file);
|
if (isEncry)
|
pos = EncryFileUtil.ENCRYHEADERSIZE;
|
|
try {
|
FileInputStream in = new FileInputStream(file);
|
|
long fileSize = file.length();
|
|
if (blockLength < 0) {
|
throw new VCIError("710017", new String[0]); //没有设定每次传输的文件大小
|
}
|
byte[] fileByte =null;
|
long temp = 0;
|
|
if (pos > 0) {
|
in.skip(pos);
|
temp += EncryFileUtil.ENCRYHEADERSIZE;
|
}
|
|
while (temp < (fileSize - blockLength)) {
|
fileByte = new byte[blockLength];
|
in.read(fileByte, 0, blockLength);
|
arrayList.add(fileByte);
|
temp += blockLength;
|
}
|
|
int remainSize = (int)(fileSize - temp);
|
fileByte = new byte[remainSize];
|
in.read(fileByte, 0, remainSize);
|
arrayList.add(fileByte);
|
in.close();
|
|
int size=arrayList.size();
|
bypes=new byte[size][];
|
|
for(int i=0;i<size;i++){
|
if (isEncry)
|
bypes[i] = RC4.encry_RC4_byte(arrayList.get(i), fileKey);
|
else
|
bypes[i] = arrayList.get(i);
|
}
|
return bypes;
|
} catch (VCIError rme) {
|
throw rme;
|
} catch (Exception e) {
|
VolumeWithLog4j.logger.error("710018", e);
|
throw new VCIError("710018", new String[0]);//下载文件出错,请重新下载!
|
}
|
}
|
|
public FileInfo[] getFileList(String path, String savePath, Current current) throws VCIError {
|
|
String svrPath = hanlderOS(path);
|
|
FileInfo[] fileInfos = null;
|
try {
|
ArrayList<FileInfo> infos = new ArrayList<FileInfo>();
|
|
String volPath = path;
|
if (volPath.endsWith("\\") || volPath.endsWith("/"))
|
volPath = volPath.substring(0, volPath.length() - 1);
|
|
String tempPath = svrPath;
|
if (tempPath.endsWith("\\") || tempPath.endsWith("/"))
|
tempPath = tempPath.substring(0, tempPath.length() - 1);
|
|
collectFiles(new File(svrPath), volPath, tempPath, infos);
|
int size = infos.size();
|
fileInfos = new FileInfo[size];
|
for (int i = 0; i < size; i++) {
|
fileInfos[i] = infos.get(i);
|
}
|
} catch (Exception e) {
|
VolumeWithLog4j.logger.error("710019", e);
|
throw new VCIError("710019", new String[0]);//获取服务器端下载文件出错,请检查服务器端文件。
|
}
|
return fileInfos;
|
}
|
|
public FileInfo[] getFolderFiles(String path, Current current) throws VCIError {
|
String svrPath = hanlderOS(path);
|
FileInfo[] fileInfos = null;
|
try {
|
List<FileInfo> infos = new ArrayList<FileInfo>();
|
File file = new File(svrPath);
|
|
StringBuffer buf = new StringBuffer();
|
|
if (file.isDirectory()) {
|
File[] subFiles = file.listFiles();
|
|
if (subFiles != null) {
|
// 文件夹的话,递归处理子文件
|
for (File subFile : subFiles) {
|
if (subFile.isDirectory())
|
continue;
|
|
buf.setLength(0);
|
buf.append(path);
|
buf.append(File.separator);
|
buf.append(file.getAbsolutePath().substring(svrPath.length() + 1));
|
|
FileInfo info = new FileInfo();
|
info.filePath = subFile.getName();
|
info.fileSavePath = "";
|
info.isDirectory = false;
|
info.fileSize = subFile.length();
|
infos.add(info);
|
}
|
}
|
}
|
|
fileInfos = infos.toArray(new FileInfo[0]);
|
|
} catch (Exception e) {
|
VolumeWithLog4j.logger.error("710019", e);
|
throw new VCIError("710019", new String[0]);//获取服务器端下载文件出错,请检查服务器端文件。
|
}
|
|
return fileInfos;
|
}
|
|
private void collectFiles(File file,String saveDir,String folderPath,List<FileInfo> infos) {
|
File[] subFiles = null;
|
StringBuffer buf = new StringBuffer();
|
|
if (!file.exists())
|
return;
|
|
if (file.isDirectory()) {
|
subFiles = file.listFiles();
|
} else if (file.getName().equals("patchVersion.properties")) {
|
return;
|
}
|
|
if (subFiles != null) {
|
// 文件夹的话,递归处理子文件
|
for (File subFile:subFiles) {
|
collectFiles(subFile,saveDir,folderPath,infos);
|
}
|
|
// 将空文件夹也添加进来,需要传过去
|
if (subFiles.length == 0) {
|
if (file.getAbsolutePath().equals(folderPath)) {
|
return;
|
}
|
buf.setLength(0);
|
buf.append(saveDir);
|
buf.append(File.separator);
|
buf.append(file.getAbsolutePath().substring(folderPath.length() + 1));
|
FileInfo info = new FileInfo();
|
info.filePath = file.getAbsolutePath();
|
info.fileSavePath = buf.toString();
|
info.isDirectory = file.isDirectory();
|
infos.add(info);
|
}
|
} else {
|
// 将文件添加进来,需要传输
|
buf.setLength(0);
|
buf.append(saveDir);
|
buf.append(File.separator);
|
|
int len = 0;
|
if (file.getAbsolutePath().length() == folderPath.length()) {
|
len = file.getAbsolutePath().lastIndexOf(File.separator);
|
} else {
|
len = folderPath.length();
|
}
|
|
buf.append(file.getAbsolutePath().substring(len + 1));
|
// buf.append(file.getAbsolutePath().substring(folderPath.length() + 1));
|
FileInfo info = new FileInfo();
|
info.filePath = file.getAbsolutePath();
|
info.fileSavePath = buf.toString();
|
info.isDirectory = file.isDirectory();
|
if (!file.isDirectory()) {
|
info.fileSize = file.length();
|
}
|
infos.add(info);
|
}
|
return;
|
}
|
|
/**
|
* 获取指定目录下的子目录
|
* @param file
|
* @param infos
|
*/
|
public String[] getSubFolders(String path, Current current) {
|
String sParent = hanlderOS(path);
|
|
File file = new File(sParent);
|
if (!file.exists() || !file.isDirectory())
|
return new String[0];
|
|
List<String> lstSubFolder = new ArrayList<String>();
|
|
File[] subFiles = file.listFiles();
|
// 文件夹的话,递归处理子文件
|
for (File subFile:subFiles) {
|
if (!subFile.isDirectory() || subFile.getName() == "." || subFile.getName()== "..")
|
continue;
|
|
lstSubFolder.add(subFile.getName());
|
}
|
|
return lstSubFolder.toArray(new String[0]);
|
}
|
|
|
/**
|
* 通过集成方式获得文件大小
|
*/
|
public long getIntegrationFileSize(String fileName, Current current) throws VCIError {
|
long size = -1;
|
try {
|
fileName = new String(fileName.getBytes("ISO-8859-1"), "GBK");
|
fileName = hanlderOS(fileName);
|
File file1 = new File(fileName);
|
if (!file1.exists()) {
|
throw new VCIError("710001", new String[]{});//文件不存在!
|
}
|
size = file1.length();
|
} catch (Exception g) {
|
//g.printStackTrace();
|
VolumeWithLog4j.logger.error("710003", g);
|
throw new VCIError("710003", new String[]{});//获取文件大小出错,请重新获取!
|
}
|
return size;
|
}
|
|
/**
|
* 集成方式服务器端发送文件
|
*/
|
public byte[] receiveIntegrationFile(String fileName, long pointoffile, Current current) throws VCIError {
|
fileName = convertISO_8859_1ToGBK(fileName);
|
fileName = hanlderOS(fileName);
|
int bak = fileName.lastIndexOf(".bak");
|
boolean lockRead = false;
|
if (pointoffile == 0 && bak > 16) { //说明是历史版本文件
|
String nameTemp = fileName.substring(0, bak);
|
lockRead = fileControl.lockRead(nameTemp);
|
}
|
else if (pointoffile == 0) {
|
lockRead = fileControl.lockRead(fileName);
|
}
|
if (pointoffile == 0 && (!lockRead)) {
|
throw new VCIError("710004", new String[]{});//("服务器端文件已锁定,请稍后再试!");
|
} else {
|
byte[] read = null;
|
File resoucefile = new File(fileName);
|
if (!resoucefile.exists()) {
|
throw new VCIError("710001", new String[]{});//("文件不存在!");
|
}
|
FileInputStream inputfile = null;
|
try {
|
inputfile = new FileInputStream(resoucefile);
|
inputfile.skip(pointoffile);
|
int len = blockLength;
|
if ((resoucefile.length() - pointoffile) <= blockLength) {
|
len = (int)(resoucefile.length() - pointoffile);
|
read = new byte[len];
|
} else {
|
read = new byte[blockLength];
|
}
|
inputfile.read(read, 0, len);
|
inputfile.close();
|
if ((resoucefile.length() - pointoffile) <= blockLength) {
|
fileControl.unlockRead(fileName);
|
}
|
} catch (Exception e1) {
|
try {
|
if (inputfile != null) {
|
inputfile.close();
|
}
|
} catch (Exception ex) {
|
}
|
fileControl.unlockRead(fileName);
|
|
VolumeWithLog4j.logger.error("710005", e1);
|
throw new VCIError("710005", new String[]{});//("服务器端发送文件出错!");
|
}
|
return read;
|
}
|
}
|
|
String convertGBKToISO_8859_1(String text){
|
return convertEncoding(text, "GBK", "ISO-8859-1");
|
}
|
String convertISO_8859_1ToGBK(String text){
|
return convertEncoding(text, "ISO-8859-1", "GBK");
|
}
|
String convertEncoding(String text, String fromEncoding, String toEncoding){
|
String res = text;
|
try {
|
res = new String(text.getBytes(fromEncoding), toEncoding);
|
} catch (UnsupportedEncodingException e) {
|
//e.printStackTrace();
|
VolumeWithLog4j.logger.error(e);
|
}
|
return res;
|
}
|
/**
|
* 测试连接
|
*/
|
public boolean testConntect() {
|
return true;
|
}
|
|
@Override
|
public boolean isFileExist(String fileName, Current current) throws VCIError {
|
fileName = hanlderOS(fileName);
|
try {
|
File currentFile = new File(fileName);
|
if (currentFile.exists()) {
|
return true;
|
}
|
} catch (Exception g) {
|
//g.printStackTrace();
|
VolumeWithLog4j.logger.error("710002", g);
|
throw new VCIError("710002", new String[0]);
|
}
|
return false;
|
}
|
|
/**
|
* 获取当前文件柜服务器Host信息(返回格式为"HostIPIP@|@HostName")[冗余存储主要解决可能由于文件柜服务器部署变更引起的问题分析, ADD By ZhongGY 2015-03-24]
|
*/
|
@Override
|
public String getHostInfo(Current current) throws VCIError {
|
try {
|
InetAddress address = InetAddress.getLocalHost();
|
return address.getHostAddress() + "@|@" + address.getHostName();
|
} catch (UnknownHostException e) {
|
//e.printStackTrace();
|
VolumeWithLog4j.logger.error(e);
|
throw new VCIError(e.getLocalizedMessage(), new String[0]);
|
}
|
}
|
|
|
/**
|
* 查询文件柜使用空间及磁盘总空间
|
*/
|
@Override
|
public VolumeUseInfo[] getVolumeUseInfo(Current current) throws VCIError {
|
|
//PvolumeDelegate pvolumeDelegate = new PvolumeDelegate();
|
PvolumeInfo[] pvolumeInfos = VolumeCacheProvider.getAllVolumes();
|
VolumeUseInfo[] volumns = new VolumeUseInfo[pvolumeInfos.length];
|
for(int i = 0; i < volumns.length; i++){
|
volumns[i] = new VolumeUseInfo();
|
volumns[i].id = pvolumeInfos[i].id;
|
volumns[i].name = pvolumeInfos[i].name;
|
volumns[i].host = pvolumeInfos[i].host;
|
volumns[i].path = pvolumeInfos[i].path;
|
volumns[i].type = pvolumeInfos[i].type;
|
volumns[i].usedSize = getUsedSize(new File(volumns[i].path));
|
volumns[i].diskSize = getDiskSize(new File(volumns[i].path));
|
}
|
return volumns;
|
}
|
|
|
private PvolumeInfo getVolumnInfo(String volumn) throws VCIError {
|
|
if (mapVolumn.containsKey(volumn))
|
return mapVolumn.get(volumn);
|
|
//PvolumeDelegate pvolumeDelegate = new PvolumeDelegate();
|
PvolumeInfo pvolume = VolumeCacheProvider.getVolume(volumn);
|
if (pvolume != null)
|
mapVolumn.put(volumn, pvolume);
|
|
return pvolume;
|
}
|
|
private String getDiskSize(File file) {
|
File[] listRoots = File.listRoots();
|
File root = null;
|
for (int i = 0; i < listRoots.length; i++) {
|
if(file.getAbsolutePath().startsWith(listRoots[i].getPath())){
|
root = listRoots[i];
|
}
|
}
|
if(root == null) return "未找到磁盘";
|
long total = root.getTotalSpace() / (1024*1024);
|
return String.valueOf(total);
|
}
|
public String getUsedSize(final File folder){
|
if(!folder.exists()) return "文件夹" + folder + "不存在";
|
if(!folder.isDirectory()) return String.valueOf(folder.length() / (1024 * 1024));
|
long total = 0;
|
try {
|
String[] listNames = folder.list();
|
if(listNames.length > 2000){
|
ExecutorService pool = Executors.newFixedThreadPool(10);
|
final int[] diff = new int[2]; //[起始index, 处理size]
|
int block = 1800;
|
List<Callable<Long>> tasks = new ArrayList<Callable<Long>>();
|
while(diff[0] < listNames.length){
|
diff[1] = listNames.length - diff[0];
|
diff[1] = diff[1] > block ? block : diff[1];
|
tasks.add(new Callable<Long>() {
|
int start = diff[0];
|
int block = diff[1];
|
@Override
|
public Long call() throws Exception {
|
return getTotalSize(folder, start, block);
|
}
|
});
|
diff[0] += diff[1];
|
}
|
List<Future<Long>> results;
|
results = pool.invokeAll(tasks);
|
pool.shutdown();
|
for(Future<Long> future : results){
|
long size = future.get();
|
total += size;
|
}
|
}else{
|
total = getTotalSize(folder, 0, listNames.length);
|
}
|
} catch (InterruptedException e) {
|
//e.printStackTrace();
|
VolumeWithLog4j.logger.error(e);
|
return "线程执行错误:" + e.getMessage();
|
} catch (ExecutionException e) {
|
//e.printStackTrace();
|
VolumeWithLog4j.logger.error(e);
|
return "计算出错:" + e.getMessage();
|
}
|
return String.valueOf(1.0*total/1024/1024);
|
}
|
private long getTotalSize(File folder, int start, int block){
|
long total = 0;
|
File[] listFiles = folder.listFiles();
|
if(start >= listFiles.length) return 0;
|
int end = start + block;
|
for (int i = start; i < end; i++) {
|
if(listFiles[i].isDirectory()){
|
total += getTotalSize(listFiles[i], 0, listFiles[i].list().length);
|
}else{
|
total += listFiles[i].length();
|
}
|
}
|
return total;
|
}
|
|
@Override
|
public boolean existPath(String filePath, Current current) throws VCIError {
|
try {
|
File currentFile = new File(filePath);
|
if (!currentFile.exists()) {
|
return false;
|
}
|
return true;
|
} catch (Exception e) {
|
return false;
|
}
|
}
|
|
@Override
|
public boolean testConntect(Current current) {
|
// TODO Auto-generated method stub
|
return true;
|
}
|
|
@Override
|
public long getTransmitBlockSize(com.zeroc.Ice.Current current) throws VCIError {
|
return VolumeProperties.blockLength();
|
}
|
}
|