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 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 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)
/**
* 获取下一级目录列表 文件+文件夹(返回list)
* @param ftp
* @param pathName
* @return
* @throws IOException
*/
public static List getNextDirectory(FTPClient ftp,String pathName) throws IOException {
log.info("Ftp中pathName:"+pathName);
List filePathList = new ArrayList();
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);// 删除文件