ftp上传文件,下载文件,断点续传,进度条,新建,删除文件,文件夹,工具

ftp上传文件,下载文件,断点续传,进度条,新建,删除文件,文件夹,工具@TOC

package com.css.sword.yhzx.common;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.text.NumberFormat;
import java.util.Map;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.log4j.Logger;
import org.eclipse.jetty.util.log.Log;

import com.css.sword.kernel.base.exception.SwordBaseCheckedException;



public class FtpUtils {
	private static Logger logger = Logger.getLogger(FtpUtils.class);
	private static FTPClient ftp;
	private static String LOCAL_CHARSET = "UTF-8";
	private static String SERVER_CHARSET = "ISO-8859-1";
	private static OutputStream os = null;
	
	
	/**
	 * 获取ftp连接
	 *
	 * @param f
	 * @return
	 * @throws Exception
	 */
	public static boolean connectFtp(Map<String, Object> paramMap) throws Exception {
		ftp = new FTPClient();
		boolean flag = false;
		int reply;
		String ipAddress = (String) paramMap.get("ftpurl");
		Integer port = (Integer) paramMap.get("port");
		String userName = (String) paramMap.get("username");
		String password = (String) paramMap.get("password");
		if (port == null) {
			ftp.connect(ipAddress, 21);
		} else {
			ftp.connect(ipAddress, port);
		}
		ftp.login(userName, password);
		ftp.enterLocalPassiveMode();
		// ftpClient.enterLocalActiveMode();// 主动模式
		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
		ftp.setDataTimeout(60000); // 设置传输超时时间为60秒
		ftp.setConnectTimeout(60000); // 连接超时为60秒
		reply = ftp.getReplyCode();
		/*if (FTPReply.isPositiveCompletion(ftp.sendCommand("OPTS UTF8", "ON"))) {
			LOCAL_CHARSET = "UTF-8";
		}*/
		ftp.setControlEncoding(LOCAL_CHARSET);
		if (!FTPReply.isPositiveCompletion(reply)) {
			ftp.disconnect();
			return flag;
		}
		ftp.changeWorkingDirectory("/");
		flag = true;
		return flag;
	}

	/**
	 * 关闭ftp连接
	 */
	public static void closeFtp() {
		if (ftp != null && ftp.isConnected()) {
			try {
				ftp.logout();

			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (ftp.isConnected()) {
					try {
						ftp.disconnect();
					} catch (IOException e2) {
						// TODO: handle exception
						e2.printStackTrace();
					}
				}
			}
		}
	}

	/**
	 * ftp上传文件
	 *
	 * @param f
	 * @throws Exception
	 */
	public static void upload1(File f,String pathName) throws Exception {
		ftp.changeWorkingDirectory(new String(pathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
		if (f.isDirectory()) {
			ftp.makeDirectory(f.getName());
			ftp.changeWorkingDirectory(f.getName());
			String[] files = f.list();
			for (String fstr : files) {
				File file1 = new File(f.getPath() + "/" + fstr);
				if (file1.isDirectory()) {
					upload1(file1,pathName);
					ftp.changeToParentDirectory();
				} else {
					File file2 = new File(f.getPath() + "/" + fstr);
					FileInputStream input = new FileInputStream(file2);
					ftp.storeFile(new String(file2.getName().getBytes(LOCAL_CHARSET), SERVER_CHARSET), input);
					input.close();
				}
			}
		} else {
			ftp.setBufferSize(1024*1024);
			File file2 = new File(f.getPath());
			FileInputStream inputStream = new FileInputStream(file2);
			BufferedInputStream input = new BufferedInputStream(inputStream);
			ftp.storeFile(new String(file2.getName().getBytes(LOCAL_CHARSET), SERVER_CHARSET), input);
			input.close();	
		}
		closeFtp();
	}

	/**
	 * FTP下载文件
	 * 
	 * @param pathname
	 *            目标文件目录路径
	 * @param filename
	 *            文件名称(带后缀)
	 * @param localpath
	 *            本地存放路径
	 * @return
	 */
	public static boolean downloadFile(String pathname, String filename, String localpath) {
		boolean flag = false;
		try {
			String newPathName = new String(pathname.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
	        
			flag =ftp.changeWorkingDirectory(newPathName);
			// 读取文件
			FTPFile[] ftpFiles = ftp.listFiles();
			for (FTPFile file : ftpFiles) {
				if (filename.equalsIgnoreCase(file.getName())) {
					File localFile = new File(localpath);
					if (!localFile.exists()) {
						localFile.mkdirs();
					}
					localFile = new File(localpath + File.separator + file.getName());
					os = new FileOutputStream(localFile);
					ftp.retrieveFile(new String(file.getName().getBytes(LOCAL_CHARSET), SERVER_CHARSET), os);
					os.close();
				}
			}
			flag = true;

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			closeFtp();
		}
		return flag;
	}

	/**
	 * 新建文件夹
	 */
	public static boolean createDir(String remote) throws UnsupportedEncodingException, IOException {
		if(!remote.endsWith("/")){
			remote = remote + "/";
		}
		boolean flag= false;
		String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
		if (!directory.equalsIgnoreCase("/") && !ftp.changeWorkingDirectory(
				new String(directory.getBytes(LOCAL_CHARSET), SERVER_CHARSET))) {
			// 如果远程目录不存在,则递归创建远程服务器目
			int start = 0;
			int end = 0;
			if (directory.startsWith("/")) {
				start = 1;
			} else {
				start = 0;
			}
			end = directory.indexOf("/", start);
			while (true) {
				String subDirectory = new String(remote.substring(start, end).getBytes(LOCAL_CHARSET), SERVER_CHARSET);
				if (!ftp.changeWorkingDirectory(subDirectory)) {
					if (ftp.makeDirectory(subDirectory)) {
						flag=ftp.changeWorkingDirectory(subDirectory);
					} else {
						logger.debug("创建目录失败");
					}
				}else{
					flag = true;
				}
				start = end + 1;
				end = directory.indexOf("/", start);
				// 检查所有目录是否创建完毕
				if (end <= start) {
					break;
				}
			}
		}else{
			flag = true;
		}
		closeFtp();
		return flag;
	}
	
	
	 /**
     * * 删除文件 *
     * 
     * @param pathname
     *            FTP服务器保存目录 *
     * @param filename
     *            要删除的文件名称 *
     * @param ftp
     * @return
	 * @throws UnsupportedEncodingException 
     */
    public static boolean deleteFile(String pathname, String filename) throws UnsupportedEncodingException {
        boolean flag = false;
        String newPathName = new String(pathname.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
        String newfilename = new String(filename.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
        try {
        	//Logger.getLogger("开始删除文件");
            // 切换FTP目录
            /*String curDirectory = ftp.printWorkingDirectory();
			if ("".equals(curDirectory)) {// 若为空,则定位到根目录
				curDirectory = "";
			}*/
            ftp.changeWorkingDirectory( "/");
			// 删除文件
			flag =ftp.changeWorkingDirectory( newPathName);// 转移到FTP服务器目录
           // ftp.changeWorkingDirectory(pathname);
            flag =ftp.deleteFile(newfilename);
            // ftp.logout();// 退出登录
            logger.debug("删除文件成功");   
        } catch (Exception e) {
        	logger.debug("删除文件失败");
            e.printStackTrace();
        } finally {
        
        }
        return flag;
    }
    
    /**
     * 删除文件夹
     * @param directoryName
     * @throws IOException
     */
    public static void removeDirectory(String pathName) throws IOException{
    	try {
    		if (pathName.startsWith("/") && pathName.endsWith("/")) {
    		String newPathName = new String(pathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
                //更换目录到当前目录
    		String beforePath = "";
    			ftp.changeWorkingDirectory("/");
                ftp.changeWorkingDirectory(newPathName);
                FTPFile[] files = ftp.listFiles();
                if(files.length >0){
	                for (FTPFile file : files) {
	                    if (file.isFile()) {                   
	                    	deleteFile(pathName , file.getName());
	                    } else if (file.isDirectory()) {
	                        if (!".".equals(file.getName()) && !"..".equals(file.getName())) {
	                        	 ftp.changeWorkingDirectory(new String(file.getName().getBytes(LOCAL_CHARSET), SERVER_CHARSET));
	                        	 FTPFile[] fileSecond = ftp.listFiles();
	                        	 if(fileSecond.length > 0){
	                        		 removeDirectory(pathName + file.getName() + "/");
	                        	 }else{ 
	                        		 ftp.changeWorkingDirectory("/");
	                        		 ftp.changeWorkingDirectory(newPathName);
	                        		 ftp.removeDirectory(new String(file.getName().getBytes(LOCAL_CHARSET), SERVER_CHARSET));
	                        	 }
	                        	
	                        }
	                    }
	                }
	                beforePath=subStringPath(pathName);
                	ftp.changeWorkingDirectory("/");
                	ftp.changeWorkingDirectory(new String(beforePath.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
                	newPathName =fileNameDelete(pathName);
                	ftp.removeDirectory(new String(newPathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
                }else {
                	beforePath=subStringPath(pathName);
                	ftp.changeWorkingDirectory("/");
                	ftp.changeWorkingDirectory(new String(beforePath.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
                	newPathName =fileNameDelete(pathName);
                	ftp.removeDirectory(new String(newPathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
				}  
            }else {
				if(!pathName.startsWith("/")){
					pathName = "/"+pathName;
				}
				if(!pathName.endsWith("/")){
					pathName = pathName + "/";
				}
				removeDirectory(pathName);
			}
    	} catch (Exception e) {
			// TODO: handle exception
    		e.printStackTrace();
		} finally {
        	closeFtp();
        }
    }
    
    private static String subStringPath (String pathName){
    	if(pathName.endsWith("/")){
    		pathName = pathName.substring(0,pathName.length()-1);
			pathName = pathName.substring(0,pathName.lastIndexOf("/"));				
    	}else{
    		pathName = pathName.substring(0,pathName.lastIndexOf("/"));
    	}
    	return pathName; 
    }
    
    private static String fileNameDelete(String pathName){
    	if(pathName.endsWith("/")){
    		pathName = pathName.substring(0,pathName.length()-1);
			pathName = pathName.substring(pathName.lastIndexOf("/")+1,pathName.length());				
    	}else{
    		pathName = pathName.substring(pathName.lastIndexOf("/"),pathName.length());
    	}
    	return pathName;
    }
    
    
    
    /**
     * 上传文件进度条
     */
    /**
     * 上传文件到FTP服务器,支持断点续传 并返回上传文件进度
     * @param local 本地文件名称,绝对路径
     * @param remote 远程文件路径,使用/home/directory1/subdirectory/file.ext
     *               按照Linux上的路径指定方式,支持多级目录嵌套,支持递归创建不存在的目录结构
     * @return 上传结果
     * @throws IOException
     */
    public static UploadStatus upload(String local, String remote) throws Exception{
        try {
            if (!ftp.isConnected()) {
               logger.debug("远程服务器相应目录创建失败");
            }
            UploadStatus result;
            // 对远程目录的处理  并返回文件的名称
            String remoteFileName = createDirectory(remote, ftp);
            // 检查远程是否存在文件
            FTPFile[] files = ftp.listFiles(remoteFileName);
            File localFile = new File(local);
            if(localFile.length() <=0){
               logger.debug("本地文件不存在");
            }
            if (files.length == 1) {
                //判断文件是否存在
                long remoteSize = files[0].getSize();
                long localSize = localFile.length();
                if(remoteSize==localSize){
                    return UploadStatus.File_Exits;
                }else if(remoteSize > localSize){
                    return UploadStatus.Remote_Bigger_Local;
                }
                result = writeByUnit(remoteFileName,localFile,ftp,remoteSize,localFile.length());
            } else {
                result = writeByUnit(remoteFileName,localFile,ftp,0,localFile.length());
            }
            return result;
        }catch (IOException e){
            throw e;
        }finally {
            //上传完成之后 切回到根目录
            ftp.changeWorkingDirectory("/");
        }
    }

    /**
     * 判断目录
     * @param remoteFilePath 远程服务器上面的 文件目录
     * @param ftpClient ftp客户端
     * @return
     * @throws Exception
     */
    private static String createDirectory(String remoteFilePath,FTPClient ftpClient) throws Exception {
        if(ftpClient == null){
           // throw new CreateException(-1,"FTP客户端为空,请先连接到客户端");
        }
        String fileName = remoteFilePath;
        if(remoteFilePath.contains("/")){
            fileName = remoteFilePath.substring(remoteFilePath.lastIndexOf("/") + 1);
            String directory = remoteFilePath.substring(0, remoteFilePath.lastIndexOf("/") + 1);
            if(directory.startsWith("/")){
                directory = directory.substring(1);
            }
            while (true){
                if(!directory.contains("/")){
                    break;
                }
                String subDirectory = directory.substring(0, directory.indexOf("/"));
                directory = directory.substring(directory.indexOf("/")+1);
                if (!ftpClient.changeWorkingDirectory(subDirectory)) {
                    if (ftpClient.makeDirectory(subDirectory)) {
                        ftpClient.changeWorkingDirectory(subDirectory);
                    } else {
                       logger.debug("创建目录失败");
                    }
                }
            }
        }
        return fileName;
    }
    
    /**
     * 上传文件到服务器,新上传和断点续传
     * @param remoteFile 远程文件名,在上传之前已经将服务器工作目录做了改变
     * @param localFile 本地文件File句柄,绝对路径
     * @param ftpClient FTPClient引用 beginSize是指文件长传开始指针位置  endSize是结束的位置 为多线程上传下载提供接口 不过该方法还需要修改
     * @return 
     * @throws IOException
     */

    private static UploadStatus writeByUnit(String remoteFile,File localFile,FTPClient ftpClient,long beginSize,long endSize) throws Exception {
        long localSize = localFile.length();
        if(endSize > localSize){
            endSize = localSize;
        }
        if(beginSize < 0){
            beginSize = 0;
        }
        //等待写入的文件大小
        long writeSize = endSize - beginSize;
        if(writeSize <= 0){
          logger.debug("文件指针参数出错");
        }
        //获取百分单位是 1-100
        RandomAccessFile raf = new RandomAccessFile(localFile,"r");
        OutputStream out = ftpClient.appendFileStream(new String(remoteFile.getBytes(LOCAL_CHARSET),SERVER_CHARSET));
        //把文件指针移动到 开始位置
        ftpClient.setRestartOffset(beginSize);
        raf.seek(beginSize);
        //定义最小移动单位是 1024字节 也就是1kb
        byte[] bytes = new byte[1024];
        int c;
        double finishSize = 0 + beginSize;
        double finishPercent = 0;
        int flag = 1;
        //存在一个bug 当分布移动的时候  可能会出现下载重复的问题 后期需要修改
        while ((c = raf.read(bytes)) != -1) {
            out.write(bytes, 0, c);
            finishSize += c;
            if(finishSize > endSize){
                finishPercent = 1;
                System.out.println(">>>>>完成进度:" + finishPercent);
             //   fileObserverAble.setKeyValue(localFile.getName(),finishPercent,"upload");
                break;
            }
            String percent="";
            if ((finishSize / endSize) - finishPercent > 0.01) {
                finishPercent = finishSize / endSize;
                percent = getPercentFormat(finishPercent,3,0);
                System.out.println(">>>>>完成进度:" + percent);
              //  fileObserverAble.setKeyValue(localFile.getName(),finishPercent,"upload");
            }else{
            	if(finishPercent > 0.99&&flag==1){
            		flag=0;
            		finishPercent = 1.0;
            		percent = getPercentFormat(finishPercent,3,0);
            		System.out.println(">>>>>完成进度:" + percent);
            	}
            }
        }
        out.flush();
        raf.close();
        out.close();
        boolean result =ftpClient.completePendingCommand();//当有返回流时才使用,用于手动结束方法
        return  result?UploadStatus.Upload_From_Break_Success:UploadStatus.Upload_From_Break_Failed;
    }
    
    private static String getPercentFormat(double d,int IntegerDigits,int FractionDigits){
		  NumberFormat nf = java.text.NumberFormat.getPercentInstance(); 
		  nf.setMaximumIntegerDigits(IntegerDigits);//小数点前保留几位
		  nf.setMinimumFractionDigits(FractionDigits);// 小数点后保留几位
		  String str = nf.format(d);
		  return str;
	}
    
    /**
     * 从FTP服务器上下载文件
     * @param remote 远程文件路径 /data/MyEclipse 2017 S2.zip
     * @param local 本地文件路径   E:\\zhanghaijie\\测试\\MyEclipse 2017 S2.zip
     * @return 是否成功
     * @throws IOException
     */
    public static boolean download(String remote,String local) throws Exception{
        FTPFile[] files = ftp.listFiles(remote);
        if(files == null || files.length < 0){
        	logger.debug("远程文件不存在");
        	return false;
        }
        if(files.length != 1){
        	logger.debug("远程文件不唯一");
        	return false;
        }
        File localFile = new File(local);
        if(localFile.exists()){
            long localBeginSize = localFile.length();
            if(localBeginSize == files[0].getSize()){
                logger.debug("文件已经存在");
            }else if(localBeginSize > files[0].getSize()){
                logger.debug("下载文件出错");
            }
            return downloadByUnit(remote,local,localBeginSize,files[0].getSize());
        }else {
            return downloadByUnit(remote,local,0,files[0].getSize());
        }
    }
    private static Boolean downloadByUnit(String remote,String local,long beginSize,long endSize) throws Exception {
        File localFile = new File(local);
        long waitSize = endSize - beginSize;
        //进行断点续传,并记录状态
        FileOutputStream out = new FileOutputStream(localFile,true);
        //把文件指针移动到 开始位置
        ftp.setRestartOffset(beginSize);
        InputStream in = ftp.retrieveFileStream(new String(remote.getBytes(LOCAL_CHARSET), SERVER_CHARSET));
        byte[] bytes = new byte[1024];
        int c;
        int flag = 1;
        double finishSize =0 + beginSize;
        double finishPercent = 0;
        while((c = in.read(bytes))!= -1){
            out.write(bytes,0,c);
            finishSize += c;
            if(finishSize > endSize){
                //System.out.println(">>>>>完成进度:" + 1);
               // fileObserverAble.setKeyValue(localFile.getName(),1,"download");

            }
            String percent = "";
            if ((finishSize / endSize) - finishPercent > 0.01) {
                finishPercent = finishSize / endSize;
                percent = getPercentFormat(finishPercent,3,0);
                System.out.println(">>>>>完成进度:" + percent);
              //  fileObserverAble.setKeyValue(localFile.getName(),finishPercent,"upload");
            }else{
            	if(finishPercent > 0.99&&flag==1){
            		flag=0;
            		finishPercent = 1.0;
            		percent = getPercentFormat(finishPercent,3,0);
            		System.out.println(">>>>>完成进度:" + percent);
            	}
            }
        }
        in.close();
        out.close();
        return ftp.completePendingCommand();
    }
    
    /**
     * 判断ftp服务器上该目录下是否文件存在
     * @throws IOException 
     */
    public static boolean checkFileIsExist(String pathName,String fileName) throws SwordBaseCheckedException, IOException{
    	boolean flag = false;

		String newPathName = new String(pathName.getBytes(LOCAL_CHARSET), SERVER_CHARSET);
		ftp.changeWorkingDirectory(newPathName);
		// 读取文件
		FTPFile[] ftpFiles = ftp.listFiles();
		for (FTPFile file : ftpFiles) {
			if (fileName.equalsIgnoreCase(file.getName())) {
				flag = true;
			}
		}
    	return flag;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值