• Java操作FTP


    使用IIS方式搭建FTP

    Windows下使用FileZilla搭建FTP

    1、与FTP服务器建立连接

    /**
     * 初始化客户端并完成对服务端的连接
     * @param server 服务端地址
     * @param port 端口号
     * @param username 用户名
     * @param password 密码
     * @param path 远程路径 值可以为空
     * @throws SocketException
     * @throws IOException
     */
    public static FTPClient connectServer(String server, int port, String username,String password, String path)  {
    	if(null == path){
    		path = "";
    	}
    	try {
    		FTPClient ftp = new FTPClient();
    		//下面四行代码必须要,而且不能改变编码格式,否则不能正确下载中文文件
    		// 如果使用serv-u发布ftp站点,则需要勾掉“高级选项”中的“对所有已收发的路径和文件名使用UTF-8编码”
    		ftp.setControlEncoding("GBK");
    		FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
    		conf.setServerLanguageCode("zh");
    		ftp.configure(conf);
    		
    		ftp.connect(server, port);
    		ftp.setDataTimeout(120000);
    
    		// 判断ftp是否存在
    		if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) {	
    			ftp.disconnect();	// 如果不存在,断开ftp连接
    			log.warn(server + "  FTP拒绝连接");
    		}
    		// 登陆ftp
    		boolean flag = ftp.login(username, password);
    		if (flag) {
    			log.info("FTP登录成功。");
    		}else {
    			log.error("FTP登录失败。");
    		}
    		
    		// 根据输入的路径,切换工作目录。这样ftp端的路径就可以使用相对路径了
    		if (path.length() != 0) {
    			if (path != null && !"".equals(path.trim())) {
    				// 对路径按照‘/’进行切割,一层一层的进入
    				String[] pathes = path.split("/");
    				for (String onepath : pathes) {
    					if (onepath == null || "".equals(onepath.trim())) {
    						continue;
    					}               
    					if (!ftp.changeWorkingDirectory(onepath)) {
    						ftp.makeDirectory(onepath);
    						boolean flagDir = ftp.changeWorkingDirectory(onepath);
    						log.info(ftp.printWorkingDirectory());
    						if (flagDir) {
    							log.info("成功连接ftp目录:" + ftp.printWorkingDirectory());
    						} else {
    							log.error("未能连接ftp目录:" + ftp.printWorkingDirectory());
    						}
    					}
    				}
    			}
    		}
    		return ftp;
    	}catch(SocketException e){
    		e.printStackTrace();
    		return null;
    	}
    	catch (IOException e) {
    		e.printStackTrace();
    		return null;
    	}
    }
    

    2、返回目录下的所有文件(包括文件夹)

    /**
     * 返回给定目录下的所有文件(包括文件夹)
     * @param path
     * @return FTPFile组成的集合
     * @throws IOException
     */
    public static List<String> getFileList(FTPClient ftp,String path) throws IOException {
    	
    	ftp.changeWorkingDirectory(path);//切换对应路径下
    	log.info("FTP当前目录:"+ftp.printWorkingDirectory());
    	FTPFile[] ftpFiles = ftp.listFiles();    // ftpFiles.length返回当前目录下的文件数
    	List retList = new ArrayList();
    	if (ftpFiles == null || ftpFiles.length == 0) {
    		return retList;
    	}
    	for (int i = 0; i < ftpFiles.length; i++) {
    		FTPFile ftpFile = ftpFiles[i];
    //		if (ftpFile.isFile()) {	// 判断是否为文件,这样返回的就是所有的文件名
    //			retList.add(ftpFile.getName());
    //		}
    		retList.add(ftpFile.getName());
    	}
    	return retList;
    }
    

    3、获取指定路径下的所有文件(不管多少文件夹下)

    /**
     * 递归遍历文件夹以及子文件夹的文件
     * 获取指定路径下的所有文件(不管多少文件夹下)
     * @param pathName 
     * @param filePathList
     * @throws IOException
     */
    public static void getFileListRecursion(FTPClient ftp,String pathName, List<String> filePathList) throws IOException {
    	
    	if(null == pathName){
    		pathName = "/";
    	}else{
    		pathName = pathName.replace("\", "/");
    	}
    	if(!pathName.startsWith("/")){
    		pathName ="/"+pathName;
    	}
    	if(!pathName.endsWith("/")){
    		pathName = pathName + "/";
    	}
    	
    	ftp.changeWorkingDirectory(pathName);
    	FTPFile[] files = ftp.listFiles();
    	for (int i = 0; i < files.length; i++) {
    		if (files[i].isFile()) {
    			log.info("得到文件:" + files[i].getName());
    			log.info("--------------");
    			filePathList.add(ftp.printWorkingDirectory()+"/"+files[i].getName());
    		} else if (files[i].isDirectory()) {
    			getFileListRecursion(ftp,pathName + files[i].getName() + "/", filePathList);
    		}
    	}
    }
    

    4、删除指定目录(递归)

    /**
     * 删除指定目录下的所有文件
     * @param ftp
     * @param pathname
     * @return
     */
    public static boolean removeAll(FTPClient ftp, String pathname) {
    	try {
    		ftp.removeDirectory(pathname);
    		FTPFile[] files = ftp.listFiles(pathname);
    		for (FTPFile f : files) {
    			if (f.isDirectory()) {
    				removeAll(ftp,pathname + "/" + f.getName());
    				boolean isDelDir = ftp.removeDirectory(pathname);
    				log.info("FTP目录是否已删除>>"+isDelDir);
    			}
    			if (f.isFile()) {
    				boolean isDelFile = ftp.deleteFile(pathname + "/" + f.getName());
    				ftp.removeDirectory(pathname);
    				log.info("FTP文件是否已删除>>"+isDelFile);
    			}
    		}
    	} catch (IOException e) {
    		e.printStackTrace();
    		return false;
    	}
    	return true;
    }
    

    5、上传文件,并重命名

    /**
     * 上传文件,并重命名.
     * @param filePathName 上传的文件,包含目录的文件名
     * @param newName 新的文件名
     * @return 上传结果,是否成功.
     * @throws IOException
     */
    public static boolean uploadFile(FTPClient ftp,String filePathName, String newName)
    		throws IOException {
    	boolean flag = false;
    	InputStream iStream = null;
    	try {
    		log.info("ftp new file name : "+newName);
    		ftp.setControlEncoding("GBK");
    		iStream = new FileInputStream(filePathName);
    		ftp.setFileType(FTPClient.BINARY_FILE_TYPE);  
    		//将当前数据连接模式设置为PASSIVE_LOCAL_DATA_CONNECTION_MODE,即:被动模式
    		ftp.enterLocalPassiveMode();
    		//将流写到服务器
    		ftp.storeFile(new String(filePathName.getBytes("GBK"),"iso-8859-1"),iStream);
    		flag = ftp.storeFile(newName, iStream);
    	} catch (IOException e) {
    		flag = false;
    		return flag;
    	} finally {
    		if (iStream != null) {
    			iStream.close();
    		}
    	}
    	return flag;
    }
    

    6、从ftp上下载文件到本地

    /**
     * 从ftp上下载文件到本地
     * @param ftpClient:ftp连接
     * @param remoteFilepath:ftp服务器端路径
     * @param localFilePath:本地路径
     * @return 是否下载成功
     */
    public static boolean downloadFileFromFtp(FTPClient ftpClient,String remoteFilepath,String localFilePath){
    	
    	boolean flag = false;
    	try {
    		//判断本地文件是否已经存在,如果已经存在,则无需下载
    		//FTPClient ftpClient = FtpUtil.connectServer(ftp);
    		File localFile = new File(localFilePath);
    		if (!localFile.exists()) {
    			InputStream inputStream = FtpUtil.downFile(ftpClient,remoteFilepath);
    			if (inputStream != null) flag = SystemUtil.inputStreamToFile(inputStream, localFilePath);
    		}else {
    			if (localFile.length() == 0) {
    				log.info("文件大小为0,即将为您重新下载!");
    				localFile.delete();
    				InputStream inputStream = FtpUtil.downFile(ftpClient,remoteFilepath);
    				if (inputStream != null) flag = SystemUtil.inputStreamToFile(inputStream, localFilePath);	// 将文件流转化为本地文件
    			}else{
    				log.info("本地文件已存在.......");
    				flag = true;
    			}
    		}
    		FtpUtil.closeServer(ftpClient);
    		return flag;
    	} catch (Exception e) {
    		flag = false;
    		log.error("从FTP下载文件到本地失败...");
    		log.error(e);
    		e.printStackTrace();
    		return flag;
    	}
    }
    	
    /**
     * 将文件流转化为本地文件
     * @param inputStream
     * @param localFilePath
     * @return boolean
     * @throws IOException 
     */
    public static boolean inputStreamToFile(InputStream inputStream,String localFilePath) throws IOException {
    	File newDir = new File(localFilePath.replace("\", "/").substring(0, localFilePath.lastIndexOf("\")));
    	if (!newDir.exists()) newDir.mkdirs();
    	FileOutputStream fs= new FileOutputStream(localFilePath);
    	try {
    		/*FileChannel fc= ((FileInputStream) inputStream).getChannel();  
    		log.info("文件大小:"+fc.size());*/
    		int bytesum = 0;
    		int byteread = 0;
    		
    		byte[] buffer = new byte[1024];
    		long startTime = System.currentTimeMillis();
    		while ((byteread = inputStream.read(buffer)) != -1) {
    			bytesum += byteread; // 字节数 文件大小
    			fs.write(buffer, 0, byteread);
    		}
    		fs.flush();
    		long endTime = System.currentTimeMillis();
    		log.info("将文件流转化为本地文件耗时/毫秒:"+(endTime-startTime));
    		return true;
    	} catch (Exception e) {
    		log.error("将文件流转化为本地文件失败",e);
    		return false;
    	}finally{
    		fs.close();
    	}
    }
    

    7、获取下一级目录列表 文件+文件夹(返回list<PathVo>)

    /**
     * 获取下一级目录列表 文件+文件夹(返回list<PathVo>)
     * @param ftp
     * @param pathName
     * @return
     * @throws IOException
     */
    public static List<PathVo> getNextDirectory(FTPClient ftp,String pathName) throws IOException {
    	log.info("Ftp中pathName:"+pathName);
    	List<PathVo> filePathList = new ArrayList<PathVo>();
    	if(null == pathName) pathName = "/";
    	else pathName = pathName.replace("\", "/");
    	if(!pathName.startsWith("/")) pathName ="/"+pathName;
    	if(!pathName.endsWith("/")) pathName = pathName + "/";
    	
    	boolean flag = ftp.changeWorkingDirectory(pathName);
    	if (!flag) {
    		log.info("重定位失败。");
    		return filePathList;
    	}
    	log.info("目录切换"+ftp.printWorkingDirectory());
    	//ftp.enterLocalActiveMode();//主动模式,默认
    	ftp.enterLocalPassiveMode();//被动模式
    	//ftp.configure(new FTPClientConfig("dist.dgp.util.fileZillaPlugin.UnixFTPEntryParser"));//FileZilla安装FTP时使用
    	String[] list = ftp.listNames();
    	System.out.println(list.length);
    	FTPFile[] files = ftp.listFiles();
    	if (files == null || files.length == 0) {
    		ftp.changeToParentDirectory();
    		return filePathList;
    	}
    	log.info("文件长度:"+files.length);
    	for (int i = 0; i < files.length; i++) {
    		PathVo vo = new PathVo();
    		if (files[i].isFile()) {
    			vo.setType("file");
    			vo.setFullPath(pathName+files[i].getName());
    			vo.setSize(formatSize(files[i].getSize()));
    			vo.setLastModified(getFileLastModified(files[i].getTimestamp().getTimeInMillis()));
    			vo.setLabel(files[i].getName());
    			vo.setExtension(files[i].getName().substring(files[i].getName().lastIndexOf(".")+1));
    			vo.setChildren(null);
    			filePathList.add(vo);
    			
    		} else if (files[i].isDirectory()) {
    			vo.setType("folder");
    			vo.setFullPath(pathName+files[i].getName());
    			vo.setLabel(files[i].getName());
    			vo.setLastModified(getFileLastModified(files[i].getTimestamp().getTimeInMillis()));
    			vo.setChildren(getNextDirectory(ftp,pathName + files[i].getName() + "/"));
    			filePathList.add(vo);
    		}
    	}
    	log.info("filePathList.size():"+filePathList.size());
    	return filePathList;
    }
    

    8、获取文件最后编辑时间

    /**
     * 获取文件最后编辑时间
     * @param filename
     * @return
     */
    public static String getFileLastModified(long timeInMillis) {
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
    	Calendar cal = Calendar.getInstance();
    	cal.setTimeInMillis(timeInMillis);
    	return sdf.format(cal.getTime());
    }
    

    9、其他

    FTPClient ftp = new FTPClient();
    
    ftp.logout();	// 关闭ftp连接
    
    ftp.setFileType(fileType);	// 设置ftp的文件传输类型
    
    ftp.changeWorkingDirectory(path);	// 改变ftp的工作目录
    
    ftp.removeDirectory(path);	// 删除一个FTP服务器上的目录(如果为空)
    
    ftp.deleteFile(pathName);	// 删除文件
    
  • 相关阅读:
    nyoj 19擅长排列的小明 (DFS)
    POJ 1321棋盘问题
    线段树与树状数组草稿
    组合博弈入门知识汇总
    组合博弈入门(题目练习及代码解析)
    pandas 连接数据库直接查表建立dataframe。loc,sort_values数据清洗操作
    Django 项目内利用ORM直接运行脚本读库
    Pandas库中的DataFrame
    利用pandas对numpy数组进行简单的科学计算
    进程池 爬去梨视频 视频资源
  • 原文地址:https://www.cnblogs.com/x54256/p/9354872.html
Copyright © 2020-2023  润新知