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;
/**
*
Title:
* Description:
* Copyright: Copyright (c) 2011
* Company: VCI
* @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 mapVolumn = new Hashtable();
Hashtable hashtable = new Hashtable();
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 uploadStateInfoMap = new ConcurrentHashMap();
/**
* 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 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 getDirMD5(String fileName,boolean listChild, Current current) throws VCIError {
fileName = hanlderOS(fileName);
File file=new File(fileName);
if(!file.isDirectory()){
return null;
}
//
Map map=new HashMap();
String md5;
File files[]=file.listFiles();
for(int i=0;i arrayList=new ArrayList();
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 infos = new ArrayList();
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 infos = new ArrayList();
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 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 lstSubFolder = new ArrayList();
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> tasks = new ArrayList>();
while(diff[0] < listNames.length){
diff[1] = listNames.length - diff[0];
diff[1] = diff[1] > block ? block : diff[1];
tasks.add(new Callable() {
int start = diff[0];
int block = diff[1];
@Override
public Long call() throws Exception {
return getTotalSize(folder, start, block);
}
});
diff[0] += diff[1];
}
List> results;
results = pool.invokeAll(tasks);
pool.shutdown();
for(Future 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();
}
}