FTP工具类开发
正所谓工欲善其事必先利其器,熟悉了下一套流程,以此铭记。
1.FTP服务搭建
由于本人使用wondiow系统,所以针对window的童鞋们可以查看。至于windowX这里配置类似,所以不要纠结于window系统不同。经过以上操作我们可以获取到ftp的用户名,密码,以及IP地址,端口号(ps:默认端口号,搭建时可以设置)
2.FTP编码集问题
由于FTP使用编码集为ISO-8859-1,所以在中文文件夹以及文件名称上传,获取服务器文件等会出现问题。有以下2中解决方案:
1.将目录、文件转码,这样就造成跟目录、文件相关的都要转码,以至于
ftpClient.changeWorkingDirectory(new String(onepath.getBytes("GBK"),"iso-8859-1"));
ftpClient.storeFile(new String(fileName.getBytes("GBK"),"iso-8859-1"), in);
ftpClient.listFiles(new String(remotePath.getBytes("GBK"),"iso-8859-1"));
那这样岂不是很麻烦,而且每次使用都需要转码,有没有更简单的呢?有,请看第2中
2.设置相应编码集等信息
ftpClient = new FTPClient();
ftpClient.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);//系统类型 这表示window系统
conf.setServerLanguageCode("zh");
ftpClient.configure(conf);
ftpClient.connect(this.ip, this.port);
这边需要注意的是顺序必须这么写
3.工具类相关
1.Jar包问题
由于本人使用maven,pom中的配置
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.5</version>
<classifier>ftp</classifier>
</dependency>
2.工具类开发
import org.apache.commons.net.ftp.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import java.io.*;
import java.util.Arrays;
import java.util.List; /**
* FTP上传工具类
*/
public class FtpUtil {
private static Logger log = LoggerFactory.getLogger(FtpUtil.class);
private final static String FILE_SEPARATOR = System.getProperties().getProperty("file.separator");
private String ip;
private String username;
private String password;
private int port = 21;
private FTPClient ftpClient = null; public FtpUtil(String serverIP, String username, String password) {
this.ip = serverIP;
this.username = username;
this.password = password;
} public FtpUtil(String serverIP, int port, String username, String password) {
this.ip = serverIP;
this.username = username;
this.password = password;
this.port = port;
} /**
* 连接ftp服务器
*/
public boolean connectServer() {
boolean result = true;
try {
ftpClient = new FTPClient();
ftpClient.setControlEncoding("GBK");
FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
conf.setServerLanguageCode("zh");
ftpClient.configure(conf);
ftpClient.connect(this.ip, this.port);
ftpClient.login(this.username, this.password);
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
int reply = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
ftpClient.disconnect();
result = false;
}
} catch (IOException e) {
e.printStackTrace();
log.error("连接ftp服务器失败", e);
result = false;
}
return result;
} /**
* 断开与ftp服务器连接
*/
public boolean closeServer() {
try {
if (ftpClient != null && ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
return true;
} catch (IOException e) {
log.error("断开与ftp服务器连接失败", e);
return false;
}
} /**
* 向FTP根目录上传文件
*
* @param localFile
* @param newName 文件名称
* @throws Exception
*/
public boolean uploadFile(String localFile, String newName) {
boolean success = false;
InputStream input = null;
try {
File file = null;
if (checkFileExist(localFile)) {
file = new File(localFile);
}
input = new FileInputStream(file);
success = ftpClient.storeFile(newName, input);
} catch (Exception e) {
log.error("FTP根目录上传文件上传失败(ps:传入文件名)", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
log.error("FTP根目录上传文件上传(ps:传入文件名),输入流关闭失败", e);
}
}
}
return success;
} /**
* 向FTP根目录上传文件
*
* @param input
* @param newName 新文件名
* @throws Exception
*/
public boolean uploadFile(InputStream input, String newName) {
boolean success = false;
try {
success = ftpClient.storeFile(newName, input);
} catch (Exception e) {
log.error("FTP根目录上传文件上传失败(ps:传入文件流)", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
log.error("FTP根目录上传文件上传(ps:传入文件流),输入流关闭失败", e);
}
}
}
return success;
} /**
* 向FTP指定路径上传文件
*
* @param localFile
* @param newName 新文件名
* @param remoteFoldPath
* @throws Exception
*/
public boolean uploadFile(String localFile, String newName, String remoteFoldPath) {
InputStream input = null;
boolean success = false;
try {
// 改变当前路径到指定路径
if (!this.changeDirectory(remoteFoldPath)) {
return false;
}
File file = null;
if (checkFileExist(localFile)) {
file = new File(localFile);
}
input = new FileInputStream(file);
success = ftpClient.storeFile(newName, input);
} catch (Exception e) {
log.error("FTP指定路径上传文件失败(ps:本地文件路径以及ftp服务器中文件名)", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
log.error("FTP指定路径上传文件失败(ps:本地文件路径以及ftp服务器中文件名),输入流关闭失败", e);
}
}
}
return success;
} /**
* 向FTP指定路径上传文件
*
* @param input
* @param newName 新文件名
* @param remoteFoldPath
* @throws Exception
*/
public boolean uploadFile(InputStream input, String newName, String remoteFoldPath) throws Exception {
boolean success = false;
try {
// 改变当前路径到指定路径
if (!this.changeDirectory(remoteFoldPath)) {
return false;
}
success = ftpClient.storeFile(newName, input);
} catch (Exception e) {
log.error("FTP指定路径上传文件失败(ps:本地文件流及ftp服务器中文件名)", e);
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
log.error("FTP指定路径上传文件失败(ps:本地文件流及ftp服务器中文件名),输入流关闭失败", e);
}
}
}
return success;
} /**
* 从FTP服务器下载文件
*
* @param remotePath FTP路径(不包含文件名)
* @param fileName 下载文件名
* @param localPath 本地路径
*/
public boolean downloadFile(String remotePath, String fileName, String localPath) {
BufferedOutputStream output = null;
boolean success = false;
try {
// 检查本地路径
if (!this.checkFileExist(localPath)) {
return false;
}
// 改变工作路径
if (!this.changeDirectory(remotePath)) {
return false;
}
// 列出当前工作路径下的文件列表
List<FTPFile> fileList = this.getFileList();
if (fileList == null || fileList.size() == 0) {
return false;
}
for (FTPFile ftpfile : fileList) {
if (ftpfile.getName().equals(fileName)) {
File localFilePath = new File(localPath + File.separator + ftpfile.getName());
output = new BufferedOutputStream(new FileOutputStream(localFilePath));
success = ftpClient.retrieveFile(ftpfile.getName(), output);
}
}
} catch (Exception e) {
log.error("FTP服务器下载文件失败", e);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
log.error("FTP服务器下载文件,输出流关闭失败", e);
}
}
}
return success;
} /**
* 从FTP服务器获取文件流
*
* @param remoteFilePath
* @return
* @throws Exception
*/
public InputStream downloadFile(String remoteFilePath) {
try {
return ftpClient.retrieveFileStream(remoteFilePath);
} catch (IOException e) {
log.error("FTP服务器获取文件流失败", e);
}
return null;
} /**
* 获取FTP服务器上[指定路径]下的文件列表
*
* @param remotePath
* @return
*/
public List<FTPFile> getFtpServerFileList(String remotePath) {
try {
FTPListParseEngine engine = ftpClient.initiateListParsing(remotePath);
return Arrays.asList(engine.getNext(25));
} catch (IOException e) {
log.error("获取FTP服务器上[指定路径]下的文件列表(getFtpServerFileList)失败", e);
}
return null;
} /**
* 获取FTP服务器上[指定路径]下的文件列表
*
* @param remotePath
* @return
*/
public List<FTPFile> getFileList(String remotePath) {
List<FTPFile> ftpfiles = null;
try {
ftpfiles = Arrays.asList(ftpClient.listFiles(remotePath));
} catch (IOException e) {
log.error("获取FTP服务器上[指定路径]下的文件列表(getFileList)失败", e);
}
return ftpfiles;
} /**
* 获取FTP服务器[当前工作路径]下的文件列表
*
* @return
*/
public List<FTPFile> getFileList() {
List<FTPFile> ftpfiles = null;
try {
ftpfiles = Arrays.asList(ftpClient.listFiles());
} catch (IOException e) {
log.error("获取FTP服务器[当前工作路径]下的文件列表失败", e);
}
return ftpfiles;
} /**
* 改变FTP服务器工作路径
*
* @param remoteFoldPath
*/
public boolean changeDirectory(String remoteFoldPath) {
boolean result = false;
try {
result = ftpClient.changeWorkingDirectory(new String(remoteFoldPath));
} catch (IOException e) {
log.error("改变FTP服务器工作路径失败", e);
}
return result;
} /**
* 删除文件
*
* @param remoteFilePath
* @return
* @throws Exception
*/
public boolean deleteFtpServerFile(String remoteFilePath) {
boolean result = false;
try {
result = ftpClient.deleteFile(remoteFilePath);
} catch (IOException e) {
log.error("FTP服务器删除文件失败", e);
}
return result;
} /**
* 删除目录
*
* @param remoteFoldPath
* @return
* @throws Exception
*/
public boolean deleteFold(String remoteFoldPath) {
boolean result = false;
try {
result = ftpClient.removeDirectory(remoteFoldPath);
} catch (IOException e) {
log.error("FTP服务器删除目录失败", e);
}
return result;
} /**
* 删除目录以及文件
*
* @param remoteFoldPath
* @return
*/
public boolean deleteFoldAndsubFiles(String remoteFoldPath) {
boolean success = false;
List<FTPFile> list = this.getFileList(remoteFoldPath);
if (list == null || list.size() == 0) {
return deleteFold(remoteFoldPath);
}
for (FTPFile ftpFile : list) {
String name = ftpFile.getName();
if (ftpFile.isDirectory()) {
success = deleteFoldAndsubFiles(remoteFoldPath + FILE_SEPARATOR + name);
} else {
success = deleteFtpServerFile(remoteFoldPath + FILE_SEPARATOR + name);
}
if (!success) {
break;
}
}
if (!success) {
return false;
}
success = deleteFold(remoteFoldPath);
return success;
} /**
* 创建目录
*
* @param remoteFoldPath
* @return
*/
public boolean createFold(String remoteFoldPath) {
boolean result = false;
try {
result = ftpClient.makeDirectory(remoteFoldPath);
} catch (IOException e) {
log.error("FTP服务器创建目录失败", e);
}
return result;
} /**
* 检查本地路径是否存在
*
* @param filePath
* @return
* @throws Exception
*/
public boolean checkFileExist(String filePath) {
return new File(filePath).exists();
} /**
* 把文件移动到特定目录下
*
* @param remoteFile
* @param remoteNewPath
* @return
*/
public boolean moveFtpServerFile(String remoteFile, String remoteNewPath) {
boolean result = false;
try {
result = ftpClient.rename(remoteFile, remoteNewPath);
} catch (IOException e) {
log.error("FTP服务器文件移动失败", e);
}
return result;
} /**
* 判断是文件还是目录
*
* @param remoteOldPath
* @return
*/
public boolean isContents(String remoteOldPath) {
return changeDirectory(remoteOldPath);
} /**
* 递归创建远程服务器目录
*
* @param dirpath 远程服务器文件绝对路径
* @return 目录创建是否成功
*/
public void createDirecroty(String dirpath) {
String directory = dirpath.substring(0, dirpath.lastIndexOf("/") + 1);
try {
if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(new String(directory))) {
// 如果远程目录不存在,则递归创建远程服务器目录
int start = 0;
int end = 0;
if (directory.startsWith("/")) {
start = 1;
} else {
start = 0;
}
end = directory.indexOf("/", start);
while (true) {
String subDirectory = new String(dirpath.substring(start, end));
if (!ftpClient.changeWorkingDirectory(subDirectory)) {
if (ftpClient.makeDirectory(subDirectory)) {
ftpClient.changeWorkingDirectory(subDirectory);
}
}
start = end + 1;
end = directory.indexOf("/", start);
// 检查所有目录是否创建完毕
if (end <= start) {
break;
}
}
}
} catch (IOException e) {
log.error("递归生成目录失败", e);
}
} /**
* 复制
*
* @param remoteOldPath
* @param remoteNewPath
* @return
*/
public boolean copyFtpServerFile(String remoteOldPath, String remoteNewPath) {
boolean copyFalg = false;
List<FTPFile> filelist;
try {
ftpClient.enterLocalPassiveMode();
filelist = this.getFileList(remoteOldPath);
int length = filelist == null || filelist.isEmpty() ? 0 : filelist.size();
String category = null;
ByteArrayOutputStream fos = null;
ByteArrayInputStream in = null;
if (length > 0) {
boolean flage = false;
if (this.isContents(remoteOldPath)) {
flage = true;
}
changeDirectory("/");
for (FTPFile ftpFile : filelist) {
category = ftpFile.getName();
if (ftpFile.isFile()) {
// 如果是文件则复制文件
ftpClient.setBufferSize(1024);
fos = new ByteArrayOutputStream();
copyFalg = ftpClient.retrieveFile(flage ? remoteOldPath + FILE_SEPARATOR + category : remoteOldPath, fos);
if (!copyFalg) {
return copyFalg;
}
// 如果读取的文件流不为空则复制文件
if (fos != null) {
in = new ByteArrayInputStream(fos.toByteArray());
copyFalg = ftpClient.storeFile(remoteNewPath + FILE_SEPARATOR + category, in);
// 关闭文件流
fos.close();
in.close();
if (!copyFalg) {
return copyFalg;
}
}
} else if (ftpFile.isDirectory()) {
// 如果是目录则先创建该目录
copyFalg = this.createFold(remoteNewPath + FILE_SEPARATOR + category);
// 再进入子目录进行递归复制
copyFtpServerFile(remoteOldPath + FILE_SEPARATOR + category, remoteNewPath + FILE_SEPARATOR + category);
}
}
}
} catch (IOException e) {
log.error("文件复制失败", e);
copyFalg = false;
}
return copyFalg;
} public static void main(String[] args) {
FtpUtil ftpUtil = new FtpUtil("", "", "");
//执行文件移动
/*if (ftpUtil.connectServer()) {
if (ftpUtil.changeDirectory("load")) {
ftpUtil.moveFtpServerFile("xlsj_h1_v0.7.apk", ".." + FILE_SEPARATOR + "down" + FILE_SEPARATOR + "1.apk");
ftpUtil.closeServer();
}
}*/
//复制 xlsj_h1_v0.8.apk是目录 xlsj_h1_v0.7.apk是文件
/* if (ftpUtil.connectServer()) {
ftpUtil.copyFtpServerFile("load/xlsj_h1_v0.8.apk", "down");
ftpUtil.copyFtpServerFile("load/xlsj_h1_v0.8.apk/xlsj_h1_v0.7.apk", "down");
ftpUtil.closeServer();
}*/ if (ftpUtil.connectServer()) {
ftpUtil.copyFtpServerFile("load/安卓上传包/安卓开发包.apk", "down");
ftpUtil.closeServer();
}
}
}
参考:
http://blog.csdn.net/iheng_scau/article/details/41682511
http://blog.163.com/biangji_and/blog/static/3382923020102491050525/
http://bbs.csdn.net/topics/390373219
http://commons.apache.org/proper/commons-net/javadocs/api-1.4.1/org/apache/commons/net/ftp/FTPClient.html
http://yangyangmyself.iteye.com/blog/1299997
FTP工具类开发的更多相关文章
- java:工具(汉语转拼音,压缩包,EXCEL,JFrame窗口和文件选择器,SFTP上传下载,FTP工具类,SSH)
1.汉语转拼音: import net.sourceforge.pinyin4j.PinyinHelper; import net.sourceforge.pinyin4j.format.HanyuP ...
- Java操作FTP工具类(实例详解)
这里使用Apache的FTP jar 包 没有使用Java自带的FTPjar包 工具类 package com.zit.ftp; import java.io.File; import java.i ...
- 静态资源上传至远程ftp服务器,ftp工具类封装
工具类,是一个单独的工程项目 提取必要信息至ftp.properties配置文件中 ftp_host=192.168.110.128 ftp_port=21 ftp_username=ftpuser ...
- ftp工具类
package com.ytd.zjdlbb.service.zjdlbb; import java.io.File;import java.io.FileInputStream;import jav ...
- 数据库模型类转换实体类的dbToPojoUtil工具类开发
idea颜色说明http://blog.csdn.net/saindy5828/article/details/53319693 1,中途运用了properties,properties.getPro ...
- Java-FtpUtil工具类
package cn.ipanel.app.newspapers.util; import java.io.BufferedReader; import java.io.DataInputStream ...
- java 工具类使用
BigDecimalUtil 金额计算工具类 import java.math.BigDecimal; public class BigDecimalUtil { private BigDecimal ...
- MSCL超级工具类(C#),开发人员必备,开发利器
MSCL超强工具类库 是基于C#开发的超强工具类集合,涵盖了日常B/S或C/S开发的诸多方面,包含上百个常用封装类(数据库操作类全面支持Mysql.Access.Oracle.Sqlserver.Sq ...
- Android 开源控件与常用开发框架开发工具类
Android的加载动画AVLoadingIndicatorView 项目地址: https://github.com/81813780/AVLoadingIndicatorView 首先,在 bui ...
随机推荐
- 修改TNSLSNR的端口
oracle 服务一启动 TNSLSNR.exe 会占用8080端口,这时,如果我们其他程序需要使用8080端口就会比较麻烦,所以需要改一下端口: 用dba账户登录 CMD>sqlplus sy ...
- Objective-C 观察者模式--简单介绍和使用
观察者模式(有时又被称为发布-订阅模式) 在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知. 这通常透过呼叫各观察者所提供的方法来实现.此种模式通常被用来实 ...
- 我也来说说DDD~大话目录
回到占占推荐博客索引 DDD之前没有接触过,但一但有了接触就一发不可收拾,他会带去进入一个全新的世界! DDD不是新技术,而是新思想,新模式,是软件开发领域的一次突破,它更接近于业务,对于业务的改动它 ...
- 2017预防bug的重要性
Bug,中文名缺陷.一个让软件测试员兴奋,让开发人员头疼的词.来源二次大战期间,一个称为"马克二型"的计算机,由于天气过热,硬件跟不上导致死机.最后发现是因为飞蛾,被继电器电死,将 ...
- Exception:HTTP Status 500 - org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)
主要错误信息如下: HTTP Status 500 - org.apache.ibatis.binding.BindingException: Invalid bound statement (not ...
- 初学Python
初学Python 1.Python初识 life is short you need python--龟叔名言 Python是一种简洁优美语法接近自然语言的一种全栈开发语言,由"龟叔&quo ...
- Trace Flag
Trace Flag能够影响Sql Server的行为,主要用于diagnose performance issue,官方解释是: Trace flags are used to temporaril ...
- 传智播客--ADO.net--SqlBulkCopy批量插入数据(小白必知)
一般情况下,我们在向数据库中插入数据时用Insert语句,但是当数据量很大的时候,这种情况就比较缓慢了,这个时候就需要SqlBulkCopy这个类. SqlBulkCopy本身常用的函数有这么几个 D ...
- 使用pudb调试python
本博客主要用于讲解如何使用pudb进行python调试: 1.安装 sudo pip install pudb pip list查看安装结果: 2.使用 测试程序: #!/usr/bin/env py ...
- 深入理解javascript函数系列第四篇——ES6函数扩展
× 目录 [1]参数默认值 [2]rest参数 [3]扩展运算符[4]箭头函数 前面的话 ES6标准关于函数扩展部分,主要涉及以下四个方面:参数默认值.rest参数.扩展运算符和箭头函数 参数默认值 ...