package com.why.ftp;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import sun.net.TelnetInputStream;
import sun.net.TelnetOutputStream;
import sun.net.ftp.FtpClient;

/**
 * ftp上传,下载
 * @author why 2009-07-30
 *
 */
public class FtpUtil {

private String ip = "";

private String username = "";

private String password = "";

private int port = -1;

private String path = "";

FtpClient ftpClient = null;

OutputStream os = null;

FileInputStream is = 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服务器
     *
     * @throws IOException
     */
    public boolean connectServer(){
        ftpClient = new FtpClient();
        try {
            if(this.port != -1){
                    ftpClient.openServer(this.ip,this.port);
            }else{
                ftpClient.openServer(this.ip);
            }
            ftpClient.login(this.username, this.password);
            if (this.path.length() != 0){
                ftpClient.cd(this.path);// path是ftp服务下主目录的子目录
            }
            ftpClient.binary();// 用2进制上传、下载
            System.out.println("已登录到\"" + ftpClient.pwd() + "\"目录");
            return true;
        }catch (IOException e){
            e.printStackTrace();
            return false;
        }
    }

/**
     * 断开与ftp服务器连接
     *
     * @throws IOException
     */
    public boolean closeServer(){
        try{
            if (is != null) {
                is.close();
            }
            if (os != null) {
                os.close();
            }
            if (ftpClient != null) {
                ftpClient.closeServer();
            }
            System.out.println("已从服务器断开");
            return true;
        }catch(IOException e){
            e.printStackTrace();
            return false;
        }
    }

/**
     * 检查文件夹在当前目录下是否存在
     * @param dir
     * @return
     */
     private boolean isDirExist(String dir){
         String pwd = "";
         try {
             pwd = ftpClient.pwd();
             ftpClient.cd(dir);
             ftpClient.cd(pwd);
         }catch(Exception e){
             return false;
         }
         return true;
     }

/**
     * 在当前目录下创建文件夹
     * @param dir
     * @return
     * @throws Exception
     */
     private boolean createDir(String dir){
         try{
            ftpClient.ascii();
            StringTokenizer s = new StringTokenizer(dir, "/"); //sign
            s.countTokens();
            String pathName = ftpClient.pwd();
            while(s.hasMoreElements()){
                pathName = pathName + "/" + (String) s.nextElement();
                try {
                    ftpClient.sendServer("MKD " + pathName + "\r\n");
                } catch (Exception e) {
                    e = null;
                    return false;
                }
                ftpClient.readServerResponse();
            }
            ftpClient.binary();
            return true;
        }catch (IOException e1){
            e1.printStackTrace();
            return false;
        }
     }

/**
      * ftp上传
      * 如果服务器段已存在名为filename的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
      *
      * @param filename 要上传的文件(或文件夹)名
      * @return
      * @throws Exception
      */
    public boolean upload(String filename){
        String newname = "";
        if(filename.indexOf("/") > -1){
            newname = filename.substring(filename.lastIndexOf("/") + 1);
        }else{
            newname = filename;
        }
        return upload(filename, newname);
    }

/**
      * ftp上传
      * 如果服务器段已存在名为newName的文件夹,该文件夹中与要上传的文件夹中同名的文件将被替换
      *
      * @param fileName 要上传的文件(或文件夹)名
      * @param newName 服务器段要生成的文件(或文件夹)名
      * @return
      */
     public boolean upload(String fileName, String newName){
         try{
             String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
             File file_in = new File(savefilename);//打开本地待长传的文件
             if(!file_in.exists()){
                 throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
             }
             if(file_in.isDirectory()){
                 upload(file_in.getPath(),newName,ftpClient.pwd());
             }else{
                 uploadFile(file_in.getPath(),newName);
             }

if(is != null){
                 is.close();
             }
             if(os != null){
                 os.close();
             }
             return true;
         }catch(Exception e){
                e.printStackTrace();
                System.err.println("Exception e in Ftp upload(): " + e.toString());
                return false;
         }finally{
             try{
                 if(is != null){
                     is.close();
                 }
                 if(os != null){
                     os.close();
                 }
             }catch(IOException e){
                 e.printStackTrace();
            }
         }
     }

/**
      * 真正用于上传的方法
      * @param fileName
      * @param newName
      * @param path
      * @throws Exception
      */
     private void upload(String fileName, String newName,String path) throws Exception{
             String savefilename = new String(fileName.getBytes("ISO-8859-1"), "GBK");
             File file_in = new File(savefilename);//打开本地待长传的文件
             if(!file_in.exists()){
                 throw new Exception("此文件或文件夹[" + file_in.getName() + "]有误或不存在!");
             }
             if(file_in.isDirectory()){
                 if(!isDirExist(newName)){
                     createDir(newName);
                 }
                 ftpClient.cd(newName);
                 File sourceFile[] = file_in.listFiles();
                 for(int i = 0; i < sourceFile.length; i++){
                     if(!sourceFile[i].exists()){
                         continue;
                     }
                     if(sourceFile[i].isDirectory()){
                         this.upload(sourceFile[i].getPath(),sourceFile[i].getName(),path+"/"+newName);
                     }else{
                         this.uploadFile(sourceFile[i].getPath(),sourceFile[i].getName());
                      }
                    }
             }else{
                 uploadFile(file_in.getPath(),newName);
             }
             ftpClient.cd(path);
     }

/**
     *  upload 上传文件
     *
     * @param filename 要上传的文件名
     * @param newname 上传后的新文件名
     * @return -1 文件不存在 >=0 成功上传,返回文件的大小
     * @throws Exception
     */
    public long uploadFile(String filename, String newname) throws Exception{
        long result = 0;
        TelnetOutputStream os = null;
        FileInputStream is = null;
        try {
            java.io.File file_in = new java.io.File(filename);
            if(!file_in.exists())
                return -1;
            os = ftpClient.put(newname);
            result = file_in.length();
            is = new FileInputStream(file_in);
            byte[] bytes = new byte[1024];
            int c;
            while((c = is.read(bytes)) != -1){
                os.write(bytes, 0, c);
            }
        }finally{
            if(is != null){
                is.close();
            }
            if(os != null){
                os.close();
            }
        }
        return result;
    }

/**
     * 从ftp下载文件到本地
     *
     * @param filename 服务器上的文件名
     * @param newfilename 本地生成的文件名
     * @return
     * @throws Exception
     */
    public long downloadFile(String filename, String newfilename){
        long result = 0;
        TelnetInputStream is = null;
        FileOutputStream os = null;
        try{
            is = ftpClient.get(filename);
            java.io.File outfile = new java.io.File(newfilename);
            os = new FileOutputStream(outfile);
            byte[] bytes = new byte[1024];
            int c;
            while ((c = is.read(bytes)) != -1) {
                os.write(bytes, 0, c);
                result = result + c;
            }
        }catch (IOException e){
            e.printStackTrace();
        }finally{
            try {
                if(is != null){
                        is.close();
                }
                if(os != null){
                    os.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

/**
     * 取得相对于当前连接目录的某个目录下所有文件列表
     *
     * @param path
     * @return
     */
    public List getFileList(String path){
        List list = new ArrayList();
        DataInputStream dis;
        try {
            dis = new DataInputStream(ftpClient.nameList(this.path + path));
            String filename = "";
            while((filename = dis.readLine()) != null){
                list.add(filename);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return list;
    }

public static void main(String[] args){
        FtpUtil ftp = new FtpUtil("133.224.202.2","tstbill","tstbill");
        ftp.connectServer();
        boolean result = ftp.upload("C:/test_why", "test_why/test");
        System.out.println(result?"上传成功!":"上传失败!");
        List list = ftp.getFileList("test_why/test");
        for(int i=0;i<list.size();i++){
            String name = list.get(i).toString();
            System.out.println(name);
        }
        ftp.closeServer();
        /**
        FTP远程命令列表
        USER    PORT    RETR    ALLO    DELE    SITE    XMKD    CDUP    FEAT
        PASS    PASV    STOR    REST    CWD     STAT    RMD     XCUP    OPTS
        ACCT    TYPE    APPE    RNFR    XCWD    HELP    XRMD    STOU    AUTH
        REIN    STRU    SMNT    RNTO    LIST    NOOP    PWD     SIZE    PBSZ
        QUIT    MODE    SYST    ABOR    NLST    MKD     XPWD    MDTM    PROT
        在服务器上执行命令,如果用sendServer来执行远程命令(不能执行本地FTP命令)的话,所有FTP命令都要加上\r\n
        ftpclient.sendServer("XMKD /test/bb\r\n"); //执行服务器上的FTP命令
        ftpclient.readServerResponse一定要在sendServer后调用
        nameList("/test")获取指目录下的文件列表
        XMKD建立目录,当目录存在的情况下再次创建目录时报错
        XRMD删除目录
        DELE删除文件
         */
    }

}

下面是FtpClient类的一些介绍:

sun.net.ftp.FtpClient.,该类库主要提供了用于建立FTP连接的类。利用这些类的方法,编程人员可以远程登录到FTP服务器,列举该服务器上的目录,设置传输协议,以及传送文件。FtpClient类涵盖了几乎所有FTP的功能,FtpClient的实例变量保存了有关建立"代理"的各种信息。下面给出了这些实例变量:

  public static boolean useFtpProxy
  这个变量用于表明FTP传输过程中是否使用了一个代理,因此,它实际上是一个标记,此标记若为TRUE,表明使用了一个代理主机。

  public static String ftpProxyHost
  此变量只有在变量useFtpProxy为TRUE时才有效,用于保存代理主机名。

  public static int ftpProxyPort
  此变量只有在变量useFtpProxy为TRUE时才有效,用于保存代理主机的端口地址。

  FtpClient有三种不同形式的构造函数,如下所示:

  1、public FtpClient(String hostname,int port)
   此构造函数利用给出的主机名和端口号建立一条FTP连接。

  2、public FtpClient(String hostname)
  此构造函数利用给出的主机名建立一条FTP连接,使用默认端口号。

  3、FtpClient()
  此构造函数将创建一FtpClient类,但不建立FTP连接。这时,FTP连接可以用openServer方法建立。

  一旦建立了类FtpClient,就可以用这个类的方法来打开与FTP服务器的连接。类ftpClient提供了如下两个可用于打开与FTP服务器之间的连接的方法。

  public void openServer(String hostname)
  这个方法用于建立一条与指定主机上的FTP服务器的连接,使用默认端口号。

  public void openServer(String host,int port)
  这个方法用于建立一条与指定主机、指定端口上的FTP服务器的连接。

  打开连接之后,接下来的工作是注册到FTP服务器。这时需要利用下面的方法。

  public void login(String username,String password)
  此方法利用参数username和password登录到FTP服务器。使用过Intemet的用户应该知道,匿名FTP服务器的登录用户名为anonymous,密码一般用自己的电子邮件地址。

  下面是FtpClient类所提供的一些控制命令。

  public void cd(String remoteDirectory):该命令用于把远程系统上的目录切换到参数remoteDirectory所指定的目录。
  public void cdUp():该命令用于把远程系统上的目录切换到上一级目录。
  public String pwd():该命令可显示远程系统上的目录状态。
  public void binary():该命令可把传输格式设置为二进制格式。
  public void ascii():该命令可把传输协议设置为ASCII码格式。
  public void rename(String string,String string1):该命令可对远程系统上的目录或者文件进行重命名操作。

  除了上述方法外,类FtpClient还提供了可用于传递并检索目录清单和文件的若干方法。这些方法返回的是可供读或写的输入、输出流。下面是其中一些主要的方法。

  public TelnetInputStream list()
  返回与远程机器上当前目录相对应的输入流。

  public TelnetInputStream get(String filename)
  获取远程机器上的文件filename,借助TelnetInputStream把该文件传送到本地。

  public TelnetOutputStream put(String filename)
  以写方式打开一输出流,通过这一输出流把文件filename传送到远程计算机

FtpClient的使用的更多相关文章

  1. Java FtpClient 实现文件上传服务

    一.Ubuntu 安装 Vsftpd 服务 1.安装 sudo apt-get install vsftpd 2.添加用户(uftp) sudo useradd -d /home/uftp -s /b ...

  2. JAVA中使用FTPClient实现文件上传下载实例代码

    一.上传文件 原理就不介绍了,大家直接看代码吧 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ...

  3. FTPClient.listFiles()不能获取文件

    今天使用ftp获取另一台服务器上的文件,发现不管切换到哪个目录,获取什么文件,调用FTPClient.listFiles()方法时返回的始终为空,但是代码又运行正常没有异常抛出. 网上查了下,发现有很 ...

  4. JAVA中使用FTPClient上传下载

    Java中使用FTPClient上传下载 在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在c ...

  5. JAVA 实现FTP上传下载(sun.net.ftp.FtpClient)

    package com.why.ftp; import java.io.DataInputStream; import java.io.File; import java.io.FileInputSt ...

  6. FTPClient使用中的问题--获取当前工作目录为null

    使用org.apache.commons.net.ftp.FTPClient 来做ftp的上传下载功能 FTPClient ftp = new FTPClient();ftp.connect(doc. ...

  7. 【FTP】C# System.Net.FtpClient库连接ftp服务器(上传文件)

    如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://net ...

  8. 【FTP】C# System.Net.FtpClient库连接ftp服务器(下载文件)

    如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://net ...

  9. Java FTPClient实现文件上传下载

    在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件 ...

  10. JAVA中使用FTPClient实现文件上传下载

    在JAVA程序中,经常需要和FTP打交道,比如向FTP服务器上传文件.下载文件,本文简单介绍如何利用jakarta commons中的FTPClient(在commons-net包中)实现上传下载文件 ...

随机推荐

  1. linux上备份Oracle时EXP-00091的错误解决方法

    unix/linux上备份Oracle时EXP-00091的错误解决方法 unix/linux上备份数据时的错误解决方法 EXP-00091: Exporting questionable stati ...

  2. 返回某个界面——nav

     NSInteger index=[[self.navigationController viewControllers]indexOfObject:self];  [self.navigationC ...

  3. linux android ndk

    Android调用so库, so库是c语言编写, 在linux 64位系统+ndk(32位)生成 lib*.so (32位) 1. 所需软件环境: 1)so库开发环境 操作系统: Redhat Ser ...

  4. VIM编辑器操作指令

    VIM有三种操作模式: 1,命令模式--command mode 2,输入模式--insert mode 3,底行模式--last line mode [在命令模式的时候,按Shift +  :出现的 ...

  5. WordPress设置固定链接和邮件提醒遇到的问题

    固定链接1.WordPress根目录下有一个.h...文件,记录文章链接类型对应的配置,要保证该文件的可写全权限:2.设置Apache2的rewrite模块启动,/etc/apache2/modle- ...

  6. Oracle创建主键自增表

    Oracle创建主键自增表   1.创建表    create table Test_Increase(            userid number(10) NOT NULL primary k ...

  7. JavaScript权威指南阅读笔记3

    第六章 对象 1.首先是先介绍了对象直接量的格式:对象直接量就是1.由若干个名/值对组成的映射表,2名/值对中间由冒号分割,3名值对之间由逗号分割,4整个映射表由花括号括起来.这样就组成了一个对象直接 ...

  8. inPolygonTest学习和C++实现

    大家好,我是小鸭酱,博客地址为:http://www.cnblogs.com/xiaoyajiang 此篇博客实现了判定平面一点是否在给定多边形内部的功能.精确,性能优良,因为只包含加法和乘法运算,效 ...

  9. 巧用Graphviz和pvtrace等工具可视化C函数调用

    http://guiquanz.github.io/2012/10/15/linux_c_call_trace/

  10. SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案

    原文:SQL Server 2008空间数据应用系列十一:提取MapInfo地图数据中的空间数据解决方案 友情提示,您阅读本篇博文的先决条件如下: 1.本文示例基于Microsoft SQL Serv ...