Chinaunix首页 | 论坛 | 博客
  • 博客访问: 514896
  • 博文数量: 107
  • 博客积分: 927
  • 博客等级: 大尉
  • 技术积分: 865
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-13 17:50
文章分类

全部博文(107)

文章存档

2014年(2)

2013年(13)

2012年(16)

2011年(76)

分类: Java

2012-05-30 18:21:10

//使用Sun的FtpClient做FTP上传下载
import sun.net.*;
import sun.net.ftp.*;
import java.io.*;
import java.util.*;
/**
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删除文件

* 针对FTP中的所有调用使用到文件名的地方请使用完整的路径名(绝对路径开始)。
*/

public class FtpUtils {
   
private FtpClient ftpclient;
   
private String ipAddress;
   
private int port;
   
private String username;
   
private String password;
   
/**
     * 构造函数
     *
@param ip String 机器IP
     *
@param port String 机器FTP端口号
     *
@param username String FTP用户名
     *
@param password String FTP密码
     *
@throws Exception
    
*/
   
public FtpUtils(String ip, int port, String username, String password) throws
            Exception {
       
this.ipAddress = ip;
       
this.port = port;
       
this.ftpclient = new FtpClient(ipAddress, port);
       
this.username = username;
       
this.password = password;
    }
   
/**
     * 构造函数
     *
@param ip String 机器IP,默认端口为21
     *
@param username String FTP用户名
     *
@param password String FTP密码
     *
@throws Exception
    
*/
   
public FtpUtils(String ip, String username, String password) throws
            Exception {
        
this(ip,21,username,password);
    }
   
/**
     * 登录FTP服务器
     *
@throws Exception
    
*/
   
public void login() throws Exception {
        ftpclient.login(username, password);
    }

   
/**
     * 退出FTP服务器
     *
@throws Exception
    
*/
   
public void logout() throws Exception {
       
//用ftpclient.closeServer()断开FTP出错时用下更语句退出
        ftpclient.sendServer("QUIT\r\n");
       
int reply = ftpclient.readServerResponse(); //取得服务器的返回信息
    }
   
/**
     * 取得指定目录下的所有文件名,不包括目录名称
     * 分析nameList得到的输入流中的数,得到指定目录下的所有文件名
     *
@param fullPath String
     *
@return ArrayList
     *
@throws Exception
    
*/
   
public ArrayList fileNames(String fullPath) throws Exception {
        ftpclient.ascii();
//注意,使用字符模式
        TelnetInputStream list = ftpclient.nameList(fullPath);
       
byte[] names = new byte[2048];//如果文件数目很多,有可能溢出
        int bufsize = 0;
        bufsize
= list.read(names, 0, names.length); //从流中读取
        list.close();
        ArrayList namesList
= new ArrayList();
       
int i = 0;
       
int j = 0;
       
while (i < bufsize ) {
           
if (names[i] == 10) { //字符模式为10,二进制模式为13
                String tempName = new String(names, j, i - j);
                namesList.add(tempName);
               
//j = i + 2; //上一次位置二进制模式
                j = i + 1; //上一次位置字符模式
            }
            i
= i + 1;
        }
       
return namesList;
    }
   
/**
     * 在FTP服务器上建立指定的目录,当目录已经存在的情下不会影响目录下的文件,这样用以判断FTP
     * 上传文件时保证目录的存在目录格式必须以"/"根目录开头
     *
@param pathList String
     *
@throws Exception
    
*/
   
public void buildRemoteDir(String pathList) throws Exception {
        ftpclient.ascii();
        StringTokenizer s
= new StringTokenizer(pathList, "/"); //sign
        int count = s.countTokens();
        String pathName
= "";
       
while (s.hasMoreElements()) {
            pathName
= pathName + "/" + (String) s.nextElement();
           
try {
                ftpclient.sendServer(
"XMKD " + pathName + "\r\n");
            }
catch (Exception e) {
                e
= null;
            }
           
int reply = ftpclient.readServerResponse();
        }
        ftpclient.binary();
    }
   
/**
     * 上传文件到FTP服务器,remote路径以FTP服务器的"/"开始,带文件名、
     * 上传文件只能使用二进制模式,当文件存在时再次上传则会覆盖
     *
@param local String
     *
@param remote String
     *
@throws Exception
    
*/
   
public void upFile(String local, String remote) throws Exception {
        buildRemoteDir(remote.substring(
0, remote.lastIndexOf("/")));
        ftpclient.binary();
//此行代码必须放在buildRemoteDir之后
        TelnetOutputStream ftpOut = ftpclient.put(remote);
  InputStream in 
= new FileInputStream(local);//
        byte[] buf = new byte[204800];
       
int bufsize = 0;
       
while((bufsize = in.read(buf, 0, buf.length)) != -1){
              ftpOut.write(buf,
0, bufsize);
        }
        in.close();
        ftpOut.close();
    }
public void buildLocalDir(String fullPath) throws Exception {

       
if(fullPath.lastIndexOf("/")<=0)return;
         String path
=fullPath.substring(0,fullPath.lastIndexOf("/"));

         File f
= new File(path);
        
if(!f.exists()){
               f.mkdirs();
         }
  }
public void downFile(String remote,String local) throws Exception {
     buildLocalDir(local);
     ftpclient.binary();
//此行代码必须放在buildRemoteDir之后
     OutputStream out=new FileOutputStream(new File(local));
     TelnetInputStream ftpIn
= ftpclient.get(remote);
    
byte[] buff=new byte[204800];
    
int len=0;
    
while((len=ftpIn.read(buff))!=-1){
           out.write(buff,
0,len);
     }
     out.close();
     ftpIn.close();
}
   
public static void main(String args[])throws Exception{
        FtpUtils upfile
=new FtpUtils("192.168.187.130","root","1-1=0");
        upfile.login();
        List list
=upfile.fileNames("/");
        System.out.println(list);
        upfile.upFile(
"FtpUtils.java","/root/xjs/test/FtpUtils.java" );
        upfile.downFile(
"/root/xjs/2.txt","xjs/2.txt" );
        upfile.logout();
    }
}
/*
以sun开头的class不是java里面的标准类,而是sun公司自己的的class,因此,他们位于rt.jar当中。因此,jdk源代码中没有提供源文件。但是,可以用诸如jad之类的反编译工具进行反编译。
实际上,基本原理就是利用Socket和ServerSocket来发送遵守FTP协议的消息,与FTP服务器进行交互。
主要用到这么几个类:
sun.net.ftp.FtpClient extends sun.net.TransferProtocolClient
sun.net.TransferProtocolClient extends sun.net.NetworkClient
sun.net.TelnetInputStream extends FilterInputStream
sun.net.TelnetOutputStream extends BufferedOutputStream
因为是使用被动模式,因此,客户端要去连接服务端,
在FtpClient的源代码的openDataConnection(String s)方法中有这么一句:
serversocket = new ServerSocket(0, 1);也就是客户端随便选择一个空闲端口。
也就是说,sun的FtpClient不支持主动模式。
*/

阅读(11127) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~