jdk 自带的ftpclient 源码解析
sun.net.ftp.FtpClient

1 首先是 create 方法: 构造FtpClient 对象

public static FtpClient create() {
    FtpClientProvider var0 = FtpClientProvider.provider();
    return var0.createFtpClient();
}

public static FtpClient create(InetSocketAddress var0) throws FtpProtocolException, IOException {
    FtpClient var1 = create();
    if (var0 != null) {
        var1.connect(var0);
    }

    return var1;
}

public static FtpClient create(String var0) throws FtpProtocolException, IOException {
    return create(new InetSocketAddress(var0, 21));
}

2 如果创建FtpClient对象的时候参数里有 host 和port 则会默认调用connect (InetSocketAddress v)方法:

如果没有,则需要客户端主动调用connect 方法

connect 方法做的事情就是创建一个socket 连接,并初始化inputstream 和outputstream 对象

public sun.net.ftp.FtpClient connect(SocketAddress var1) throws FtpProtocolException, IOException {
    return this.connect(var1, -1);
}

public sun.net.ftp.FtpClient connect(SocketAddress var1, int var2) throws FtpProtocolException, IOException {
    if (!(var1 instanceof InetSocketAddress)) {
        throw new IllegalArgumentException("Wrong address type");
    } else {
        this.serverAddr = (InetSocketAddress)var1;
        this.tryConnect(this.serverAddr, var2);
        if (!this.readReply()) {
            throw new FtpProtocolException("Welcome message: " + this.getResponseString(), this.lastReplyCode);
        } else {
            this.welcomeMsg = this.getResponseString().substring(4);
            return this;
        }
    }
}

--------------------

private void tryConnect(InetSocketAddress var1, int var2) throws IOException {
    if (this.isConnected()) {
        this.disconnect();
    }

    this.server = this.doConnect(var1, var2);

    try {
        this.out = new PrintStream(new BufferedOutputStream(this.server.getOutputStream()), true, encoding);
    } catch (UnsupportedEncodingException var4) {
        throw new InternalError(encoding + "encoding not found", var4);
    }

    this.in = new BufferedInputStream(this.server.getInputStream());
}

---------------

private Socket doConnect(InetSocketAddress var1, int var2) throws IOException {
    Socket var3;
    if (this.proxy != null) {
        if (this.proxy.type() == Type.SOCKS) {
            var3 = (Socket)AccessController.doPrivileged(new PrivilegedAction<Socket>() {
                public Socket run() {
                    return new Socket(FtpClient.this.proxy);
                }
            });
        } else {
            var3 = new Socket(Proxy.NO_PROXY);
        }
    } else {
        var3 = new Socket();
    }

    if (var2 >= 0) {
        var3.connect(var1, var2);
    } else if (this.connectTimeout >= 0) {
        var3.connect(var1, this.connectTimeout);
    } else if (defaultConnectTimeout > 0) {
        var3.connect(var1, defaultConnectTimeout);
    } else {
        var3.connect(var1);
    }

    if (this.readTimeout >= 0) {
        var3.setSoTimeout(this.readTimeout);
    } else if (defaultSoTimeout > 0) {
        var3.setSoTimeout(defaultSoTimeout);
    }

    return var3;
}

 

3 然后是登录操作:

public sun.net.ftp.FtpClient login(String var1, char[] var2) throws FtpProtocolException, IOException {
    if (!this.isConnected()) {
        throw new FtpProtocolException("Not connected yet", FtpReplyCode.BAD_SEQUENCE);
    } else if (var1 != null && var1.length() != 0) {
        this.tryLogin(var1, var2);
        StringBuffer var4 = new StringBuffer();

        for(int var5 = 0; var5 < this.serverResponse.size(); ++var5) {
            String var3 = (String)this.serverResponse.elementAt(var5);
            if (var3 != null) {
                if (var3.length() >= 4 && var3.startsWith("230")) {
                    var3 = var3.substring(4);
                }

                var4.append(var3);
            }
        }

        this.welcomeMsg = var4.toString();
        this.loggedIn = true;
        return this;
    } else {
        throw new IllegalArgumentException("User name can't be null or empty");
    }
}

public sun.net.ftp.FtpClient login(String var1, char[] var2, String var3) throws FtpProtocolException, IOException {
    if (!this.isConnected()) {
        throw new FtpProtocolException("Not connected yet", FtpReplyCode.BAD_SEQUENCE);
    } else if (var1 != null && var1.length() != 0) {
        this.tryLogin(var1, var2);
        if (this.lastReplyCode == FtpReplyCode.NEED_ACCOUNT) {
            this.issueCommandCheck("ACCT " + var3);
        }

        StringBuffer var4 = new StringBuffer();
        if (this.serverResponse != null) {
            Iterator var5 = this.serverResponse.iterator();

            while(var5.hasNext()) {
                String var6 = (String)var5.next();
                if (var6 != null) {
                    if (var6.length() >= 4 && var6.startsWith("230")) {
                        var6 = var6.substring(4);
                    }

                    var4.append(var6);
                }
            }
        }

        this.welcomeMsg = var4.toString();
        this.loggedIn = true;
        return this;
    } else {
        throw new IllegalArgumentException("User name can't be null or empty");
    }
}

------------

可以看到这个方法先发送了一个USER命令  ,发现需要密码,有发送了一个 PASS 命令

private void tryLogin(String var1, char[] var2) throws FtpProtocolException, IOException {
    this.issueCommandCheck("USER " + var1);
    if (this.lastReplyCode == FtpReplyCode.NEED_PASSWORD && var2 != null && var2.length > 0) {
        this.issueCommandCheck("PASS " + String.valueOf(var2));
    }
}

4 用户登录成功之后可以进行其他操作

首先设置一些 属性

java网络学习之 FtpClient 源码解析(8)

然后可以切换目录

java网络学习之 FtpClient 源码解析(8)

还可以上传文件

java网络学习之 FtpClient 源码解析(8)

 

下载文件

java网络学习之 FtpClient 源码解析(8)

查看文件列表

java网络学习之 FtpClient 源码解析(8)

 

删除目录 删除文件,重命名文件

java网络学习之 FtpClient 源码解析(8)

public abstract FtpClient deleteFile(String var1) throws FtpProtocolException, IOException;

还可以获取一些配置信息,文件信息或者连接信息

java网络学习之 FtpClient 源码解析(8)

 

 

5 上传文件的源码

public OutputStream putFileStream(String var1, boolean var2) throws FtpProtocolException, IOException {
    String var3 = var2 ? "STOU " : "STOR ";
    Socket var4 = this.openDataConnection(var3 + var1);
    if (var4 == null) {
        return null;
    } else {
        boolean var5 = this.type == TransferType.BINARY;
        return new TelnetOutputStream(var4.getOutputStream(), var5);
    }
}

public sun.net.ftp.FtpClient putFile(String var1, InputStream var2, boolean var3) throws FtpProtocolException, IOException {
    String var4 = var3 ? "STOU " : "STOR ";
    short var5 = 1500;
    if (this.type == TransferType.BINARY) {
        Socket var6 = this.openDataConnection(var4 + var1);
        OutputStream var7 = this.createOutputStream(var6.getOutputStream());
        byte[] var8 = new byte[var5 * 10];

        int var9;
        while((var9 = var2.read(var8)) >= 0) {
            if (var9 > 0) {
                var7.write(var8, 0, var9);
            }
        }

        var7.close();
    }

    return this.completePending();
}

 

 

相关文章:

  • 2022-01-03
  • 2021-12-14
  • 2021-10-18
  • 2021-08-27
  • 2021-06-27
  • 2021-10-10
  • 2023-03-20
猜你喜欢
  • 2021-07-10
  • 2022-12-23
  • 2022-12-23
  • 2021-06-18
  • 2021-08-08
  • 2021-05-17
  • 2021-11-22
相关资源
相似解决方案