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(); } }