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); // 删除文件