浏览 8187 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (9) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-08-05
这段代码是对apache.commons.net.ftp的一个封装。 封装原因:项目中多处使用apache.commons.net.ftp时不方便 封装后的功能: 1.统一配置客户端建立连接,项目中直接调用ftp操作函数 2.可以选择手动控制连接,亦可选择自动控制连接 3.现有的功能:上传、下载、列表、删除 具体使用后面我会贴出一个测试类。 现在开始贴代码: 一、FTP客户端封装主类 /** * * FTP客户端 * * @author bleet (mailto:liuqiang2004456@163.com) */ public class FtpClient { private FTPClient client = null; private static FtpClient instance = null; private FtpClientConfig config = null; private Logger log = null; /** 当前工作目录,每次关闭连接要回复到null,因为当前类是单例类 */ private String workDirectory = null; /** 是否手工控制连接 */ private boolean handSwitch = false; /** true表示已经登录到ftp服务器 */ private boolean ready = false; /** * 初始化参数配置及创建commons.net.ftp的客户端 * */ private FtpClient(String configFile){ log = Logger.getLogger(getClass()); client = new FTPClient(); config = FtpClientConfig.getInstance(configFile); /** 日志输出 */ client.addProtocolCommandListener( new PrintCommandListener( new PrintWriter(System.out))); client.setControlEncoding(config.getRemoteEncoding()); // 设置当前工作目录 workDirectory = config.getRootPath(); } /** * 获取ftp客户端的实例 * @return */ public static FtpClient getInstance(String configFile) { if(instance == null) instance = new FtpClient(configFile); return instance; } /** * 连接ftp * @return * @throws SocketException * @throws IOException */ private boolean connect() throws SocketException, IOException { client.connect(config.getServer(), Integer.valueOf(config.getPort())); int reply; reply = client.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)){ client.disconnect(); log.info("FTP server refused connection."); return false; } return true; } /** * 登入ftp * @return * @throws IOException */ private boolean login() throws IOException{ if (!client.login(config.getUsername(), config.getPassword())) { client.logout(); log.info("FTP server login fail."); return false; } return true; } /** * 连接然后登入统一入口 * @return * @throws SocketException * @throws IOException */ public boolean ready() throws SocketException, IOException { if(connect() && login()){ setConfig(); ready = true; return true; } return false; } /** * ftp运行环境参数配置 * @throws IOException */ private void setConfig() throws IOException{ FTPClientConfig conf = new FTPClientConfig(config.getFTPStyle()); client.configure(conf); // 被动传输模式 if(config.getPassiveMode()) client.enterLocalPassiveMode(); // 二进制传输模式 if (config.getBinaryFileType()) client.setFileType(FTP.BINARY_FILE_TYPE); // 设置当前工作目录 client.changeWorkingDirectory(getWorkDirectory()); } /** * 关闭连接 * @throws IOException */ public void close() throws IOException { if(client.isConnected()){ client.logout(); client.disconnect(); // 也可设置为null workDirectory = config.getRootPath(); } ready = false; } /** * 获取等前工作目录的文件列表 * @return * @throws IOException */ public String[] listFiles() throws IOException { if (!setReady()) { return null; } FTPFile[] files = client.listFiles(); int filesLength = files.length; String[] fileNameArr = new String[filesLength]; for (int i = 0; i < filesLength; i++) { fileNameArr[i] = files[i].getName(); } setClose(); return fileNameArr; } /** * 上传文件,文件名方式 * @param path * @param name * @return * @throws IOException */ public boolean upload(String path, String name, String remoteName) throws IOException { if (!setReady()) { return false; } FileInputStream fis = new FileInputStream(path+name); if(client.storeFile(getWorkDirectory()+remoteName, fis)){ log.info(" upload success !!! "); fis.close(); setClose(); return true; } fis.close(); setClose(); log.info(" upload fail !!! "); return false; } /** * 上传文件,流方式 * @param path * @param name * @return * @throws IOException */ public boolean upload (InputStream stream, String name, String remoteName) throws IOException { if (!setReady()) { return false; } if(client.storeFile(getWorkDirectory() + remoteName, stream)){ log.info(" upload success !!! "); stream.close(); setClose(); return true; } stream.close(); setClose(); log.info(" upload fail !!! "); return false; } /** * 下载文件 * @param path * @param name * @return * @throws UnsupportedEncodingException * @throws IOException */ public boolean download (String path, String name) throws UnsupportedEncodingException, IOException { if (!setReady()) { return false; } FileOutputStream fos = new FileOutputStream(path + name); if (client.retrieveFile(new String(name.getBytes(config.getLocalEncoding()),config.getRemoteEncoding()), fos)) { log.info("download success !!! "); fos.close(); setClose(); return true; } fos.close(); setClose(); log.info(" download fail !!! "); return false; } /** * 删除文件 * @param path * @param name * @return * @throws IOException */ public boolean removeFile(String path, String name) throws IOException { if (!setReady()) { return false; } client.changeWorkingDirectory(config.getRootPath()+path); if(client.deleteFile(name)){ log.info("remove file success !!! "); setClose(); return true; } setClose(); log.info(" remove file fail !!! "); return false; } /** * 改变工作目录 * @param path * @throws IOException */ public void setWorkDirectory(String path) throws IOException { workDirectory = (config.getRootPath()+path); // 如果是手动控制可以设置改变工作目录 if(handSwitch){ client.changeWorkingDirectory(workDirectory); } } /** * 创建目录 * @param pathname * @return * @throws IOException */ public boolean createDirectory(String pathname) throws IOException { if (!setReady()) { return false; } boolean okFlag = client.makeDirectory(pathname); setClose(); return okFlag; } /** * 获取当前工作目录 * @return */ public String getWorkDirectory() { return workDirectory; } /** * 准备FTP连接环境 * @return * @throws SocketException * @throws IOException */ private boolean setReady() throws SocketException, IOException{ if (!ready) { if (!ready()) { log.error("Ftp ready fail."); if(client.isConnected()) client.disconnect(); return false; } } ready = true; return true; } /** * 设置是否ftp连接 * @throws IOException */ private void setClose() throws IOException{ if(!handSwitch) close(); } /** * 打开手动连接 * */ public void openHandSwitch() { handSwitch = true; } /** * 关闭手动连接 * */ public void closeHandSwitch() { handSwitch = false; } } 二、读取配置文件类 /** * * FTP客户端的配置 * * @author bleet (mailto:liuqiang2004456@163.com) */ public final class FtpClientConfig { /** ftp服务器地址 */ private String server; /** ftp服务器端口 */ private String port; /** ftp服务器用户名 */ private String username; /** ftp服务器密码 */ private String password; /** ftp服务器显示风格 一般为unix 或者nt*/ private String FTPStyle; /** 本地编码格式 */ private String localEncoding; /** 远程编码格式 */ private String remoteEncoding; /** 是否设置 passiveMode模式 */ private boolean passiveMode; /** 是否设置以二进制传输文件 */ private boolean binaryFileType; /** ftp服务器工作根目录 */ private String rootPath; /** 配置文件 */ private String file; /** 单例 */ private static FtpClientConfig instance = null; private Logger log; /** * 初始化参数 * */ private FtpClientConfig(String file) { try { log = Logger.getLogger(getClass()); this.file = file; initConfig(); } catch (Exception e) { log.error("FTP::读取配置文件错误."); } } /** * 获取配置实例 * @param file * @return */ public static FtpClientConfig getInstance(String file) { if(null == instance) instance = new FtpClientConfig(file); return instance; } /** * 读取配置文件 * @param prop * @return * @throws Exception */ private String getProperty(String prop) throws Exception { BufferedReader br = null; try { InputStream inStream = new FileInputStream(new File(file)); br = new BufferedReader(new InputStreamReader(inStream)); String temp = null; do{ temp = br.readLine(); if (temp == null) break; if (temp.startsWith("#")) continue; int index = temp.indexOf("="); if (index == -1) continue; String key = temp.substring(0, index).trim(); String value = temp.substring(index + 1).trim(); if (key.equals(prop)) { br.close(); return value; } }while (temp != null); br.close(); return null; } catch (Exception e) { if (br != null) br.close(); throw e; } } /** * 设置属性 * @throws Exception */ private void initConfig() throws Exception{ setServer(getProperty("server")); setPort(getProperty("port")); setUsername(getProperty("username")); setPassword(getProperty("password")); setFTPStyle(getProperty("ftpstyle")); setLocalEncoding(getProperty("localencoding")); setRemoteEncoding(getProperty("remoteencoding")); setPassiveMode(getProperty("passivemode")); setBinaryFileType(getProperty("binaryfiletype")); setRootPath(getProperty("rootpath")); } /** * 读取二进制传输方式设置 * @return */ public boolean getBinaryFileType() { return binaryFileType; } /** * 默认以二进制形式传输文件 * @param binaryFileType */ public void setBinaryFileType(String binaryFileType) { if(null == binaryFileType){ this.binaryFileType = true; }else { if("".equals(binaryFileType.trim())){ this.binaryFileType = true; }else if ("true".equals(binaryFileType.trim())) { this.binaryFileType = true; }else if ("false".equals(binaryFileType.trim())) { this.binaryFileType = false; } } } public String getLocalEncoding() { return localEncoding; } /** * 默认编码为UTF-8 */ public void setLocalEncoding(String encoding) { if(null == encoding){ localEncoding = "UTF-8"; }else { if("".equals(encoding.trim())) localEncoding = "UTF-8"; } this.localEncoding = encoding.trim(); } public String getRemoteEncoding() { return remoteEncoding; } /** * 默认编码为UTF-8 */ public void setRemoteEncoding(String encoding) { if(null == encoding){ this.remoteEncoding = "UTF-8"; }else { if("".equals(encoding.trim())) remoteEncoding = "UTF-8"; } this.remoteEncoding = encoding.trim(); } public String getFTPStyle() { return FTPStyle; } /** * 默认NT风格 * @param style */ public void setFTPStyle(String style) { if(null == style){ this.FTPStyle = FTPClientConfig.SYST_NT; }else { if("".equals(style.trim())){ this.FTPStyle = FTPClientConfig.SYST_NT; }else if ("unix".equals(style.trim())) { this.FTPStyle = FTPClientConfig.SYST_UNIX; }else if ("nt".equals(style.trim())) { this.FTPStyle = FTPClientConfig.SYST_NT; } } } public boolean getPassiveMode() { return passiveMode; } /** * 默认支持passiveMode * @param passiveMode */ public void setPassiveMode(String passiveMode) { if(passiveMode == null){ this.passiveMode = true; }else { if("".equals(passiveMode.trim())){ this.passiveMode = true; }else if ("true".equals(passiveMode.trim())) { this.passiveMode = true; }else if ("false".equals(passiveMode.trim())) { this.passiveMode = false; } } } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getPort() { return port; } /** * 默认端口为21 * @param port */ public void setPort(String port) { if( null == port ){ port = "21"; }else { if("".equals(port.trim())) port = "21"; } this.port = port.trim(); } public String getRootPath() { return rootPath; } /** * 默认根目录为"/" * @param rootPath */ public void setRootPath(String rootPath) { if( null == rootPath ){ rootPath = "/"; }else { if("".equals(rootPath.trim())) rootPath = "/"; } this.rootPath = rootPath.trim(); } public String getServer() { return server; } public void setServer(String server) { this.server = server; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } } 三、配置文件 server=10.1.1.1 port=21 username=username password=password ftpstyle=unix localencoding=GBK remoteencoding=GBK passivemode=true binaryfiletype=true rootpath=/fileserver/ftp/ 四、测试类 其中onconnet表示手动控制连接用法 public class Test { private static FtpClient client = FtpClient.getInstance("D:/ftpconf.properties"); /** * @param args */ public static void main(String[] args) { try { //getFileList(); //download("C:/", "startadmin.sh"); //uoload(); oneconnect(); } catch (IOException e) { e.printStackTrace(); } } public static void getFileList() throws IOException{ String [] res = client.listFiles(); for (int i = 0; i < res.length; i++) { System.out.println("---------------"+i+"--------------"+res[i]); } } public static void download(String path, String filename) throws IOException{ client.download(path, filename); } /** * 三个变量顺次为 本地路径 本地文件名 远端文件名 * @throws IOException */ public static void uoload() throws IOException{ client.upload("C:/", "a.txt", "b.txt"); } public static void oneconnect() throws IOException{ client.openHandSwitch(); if(!client.ready()){ client.close(); }else { getFileList(); download("C:/", "startadmin.sh"); uoload(); } client.close(); client.closeHandSwitch(); } } 代码贴完了,大家开始拍砖吧! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-08-08
提提意见啊,一个个都是过路人~~~
|
|
返回顶楼 | |
发表时间:2009-08-10
公司里我现在主要负责后台方面的开发任务。业务主要是电信行业里的一些报表查询及上报。故经常需要使用到 FTP把相关数据文件上传至指定服务器,所以对FTP的相关API有所了解。
简单看了一下代码,感觉需要改进。 |
|
返回顶楼 | |
发表时间:2009-08-10
刚才不好意思,还没有写完,一不小心按错了键 就发送了,对不起了。
需要改进的地方,比如 不应该把 FTPClient类设计成单例类。 例如,对我们(像后台的程序)来说,大部分时候用多线程来并发进行 的,使用了单例方式就大大影响了 程序执行的速度。 仅属个人愚见,请高手们多多指教。 |
|
返回顶楼 | |
发表时间:2009-08-10
liulyx 写道 大部分时候用多线程来并发进行
的,使用了单例方式就大大影响了 程序执行的速度。 不太明白,使用单例为什么会影响多线程执行的速度?我写成单例主要是为了去掉读配置文件的操作。 |
|
返回顶楼 | |