通过socket实现两台FTP服务器指定目录下的文件转移,其中包含了基础了ftp文件列表显示、上传和下载。这里仅供学习用,需掌握的点有socket、ftp命令、文件流读取转换等

完整代码如下:

FtpFileTransfer.java

package com.xxx.ftp.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer; import com.xxx.ftp.model.ConnectInfo;
import com.xxx.ftp.model.FtpServerInfo; public class FtpFileTransfer { /**
* 文件转移
*
* @param source
* 源ftp文件目录
* @param dest
* 目标ftp文件目录
* @throws IOException
*/
public void transfer(FtpServerInfo source, FtpServerInfo dest) throws IOException {
// 源ftp目录下的文件列表
sendCommand(source.getConnect(), "CWD " + source.getDir());
sendCommand(source.getConnect(), "PASV");
String response = readNewMessage(source.getConnect());
String[] ipPort = getIPPort(response); String ip = ipPort[0];
int port = Integer.valueOf(ipPort[1]);
Socket dataSocket = new Socket(ip, port);
sendCommand(source.getConnect(), "LIST"); BufferedReader br = new BufferedReader(new InputStreamReader(dataSocket.getInputStream()));
// 读取源服务器的目录下所有文件名称
List<String> fileNameList = new ArrayList<String>();
String s = "";
while ((s = br.readLine()) != null) {
String fileInfo = new String(s.getBytes("ISO-8859-1"), "utf-8");
String[] arr = fileInfo.split("\\s+");
String fileName = arr[arr.length - 1];
fileNameList.add(fileName);
System.out.println(fileName);
} if (fileNameList.size() > 0) {
for (Iterator iterator = fileNameList.iterator(); iterator.hasNext();) {
// 根据文件名获取文件流
String fileName = (String) iterator.next();
sendCommand(source.getConnect(), "PASV");
response = readNewMessage(source.getConnect());
ipPort = getIPPort(response);
ip = ipPort[0];
port = Integer.valueOf(ipPort[1]);
Socket sourceDataSocket = new Socket(ip, port);
sendCommand(source.getConnect(), "RETR " + source.getDir() + "/" + fileName);
InputStream inputStream = sourceDataSocket.getInputStream(); // 文件流通过socket传输至目标ftp服务器文件目录下(输入流->输出流)
sendCommand(dest.getConnect(), "PASV");
response = readNewMessage(dest.getConnect());
ipPort = getIPPort(response);
ip = ipPort[0];
port = Integer.valueOf(ipPort[1]);
Socket destDataSocket = new Socket(ip, port);
sendCommand(dest.getConnect(), "STOR " + dest.getDir() + "/" + fileName);
OutputStream outputStream = destDataSocket.getOutputStream(); int offset;
byte[] bytes = new byte[1024];
while ((offset = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, offset);
}
inputStream.close();
outputStream.close();
dataSocket.close();
}
} System.out.println("transfer success!"); } /**
* ftp服务器连接
*
* @param ftpServerInfo
* ftp服务器信息 包含用户名 密码
* @return
* @throws IOException
*/
public ConnectInfo connect(FtpServerInfo ftpServerInfo) throws IOException {
Socket socket = new Socket(ftpServerInfo.getHost(), ftpServerInfo.getPort());
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); ConnectInfo connectInfo = new ConnectInfo();
connectInfo.setSocket(socket);
connectInfo.setWriter(writer);
connectInfo.setReader(reader); sendCommand(connectInfo, "USER " + ftpServerInfo.getUser());
sendCommand(connectInfo, "PASS " + ftpServerInfo.getPass());
return connectInfo;
} /**
* 断开ftp服务器连接
*
* @param connectInfo
* @throws IOException
*/
public void disconnect(ConnectInfo connectInfo) throws IOException {
if (connectInfo.getSocket() == null || !connectInfo.getSocket().isConnected()) {
return;
}
connectInfo.getSocket().close();
} /**
* 发送ftp命令
*
* @param connectInfo
* ftp服务器连接信息
* @param command
* ftp命令
* @throws IOException
*/
private void sendCommand(ConnectInfo connectInfo, String command) throws IOException {
if (command == null || command == "") {
return;
}
connectInfo.getWriter().write(command + "\r\n");
connectInfo.getWriter().flush();
} /**
* 根据连接读取ftp信息
*
* @param connect
* @return
* @throws IOException
*/
private String readNewMessage(ConnectInfo connect) throws IOException {
String response = null;
while (true) {
response = connect.getReader().readLine();
if (response == null || response.length() == 0) {
return null;
}
String rexp = "Entering Passive Mode";
if (response.contains(rexp)) {
break;
}
}
return response;
} /**
* 获取ip和端口
*
* @param response
* @return
* @throws IOException
*/
private String[] getIPPort(String response) throws IOException {
String[] ret = new String[2];
String ip = null;
int port = -1;
int opening = response.indexOf('(');
int closing = response.indexOf(')', opening + 1); if (closing > 0) {
String dataLink = response.substring(opening + 1, closing);
StringTokenizer tokenizer = new StringTokenizer(dataLink, ","); try {
ip = tokenizer.nextToken() + "." + tokenizer.nextToken() + "." + tokenizer.nextToken() + "."
+ tokenizer.nextToken();
port = Integer.parseInt(tokenizer.nextToken()) * 256 + Integer.parseInt(tokenizer.nextToken());
} catch (Exception e) {
throw new IOException("SimpleFTP received bad data link information: " + response);
}
}
ret[0] = ip;
ret[1] = String.valueOf(port);
return ret;
} public static void main(String[] args) throws IOException {
FtpFileTransfer ft = new FtpFileTransfer(); // 源ftp服务器
FtpServerInfo source = new FtpServerInfo();
source.setHost("192.168.11.129");
source.setUser("haoxr");
source.setPass("123456");
source.setDir("/home/haoxr/test");
ConnectInfo sourceConnectInfo = ft.connect(source);
source.setConnect(sourceConnectInfo); // 目标ftp服务器
FtpServerInfo dest = new FtpServerInfo();
dest.setHost("192.168.11.130");
dest.setUser("haoxr");
dest.setPass("123456");
dest.setDir("/home/haoxr/test");
ConnectInfo destConnectInfo = ft.connect(dest);
dest.setConnect(destConnectInfo); // 文件转移
ft.transfer(source, dest);
ft.disconnect(sourceConnectInfo);
ft.disconnect(destConnectInfo);
} }

ConnectInfo.java    (javabean)

package com.xxx.ftp.model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.net.Socket; public class ConnectInfo { private Socket socket;
private BufferedReader reader;
private BufferedWriter writer; public Socket getSocket() {
return socket;
} public void setSocket(Socket socket) {
this.socket = socket;
} public BufferedReader getReader() {
return reader;
} public void setReader(BufferedReader reader) {
this.reader = reader;
} public BufferedWriter getWriter() {
return writer;
} public void setWriter(BufferedWriter writer) {
this.writer = writer;
} }

FtpServerInfo.java  (javabean)

package com.xxx.ftp.model;

public class FtpServerInfo {

    public FtpServerInfo() {
this.port = 21;
} private String host;
private int port;
private String user;
private String pass; private ConnectInfo connect; public ConnectInfo getConnect() {
return connect;
} public void setConnect(ConnectInfo connect) {
this.connect = connect;
} /** 文件目录 */
String dir; public String getHost() {
return host;
} public void setHost(String host) {
this.host = host;
} public int getPort() {
return port;
} public void setPort(int port) {
this.port = port;
} public String getUser() {
return user;
} public void setUser(String user) {
this.user = user;
} public String getPass() {
return pass;
} public void setPass(String pass) {
this.pass = pass;
} public String getDir() {
return dir;
} public void setDir(String file) {
this.dir = file;
} public static void main(String[] args) {
FtpServerInfo fs=new FtpServerInfo();
String pass=fs.getPass();
System.out.println(pass); fs=new FtpServerInfo();
fs.setPass("123456");
pass=fs.getPass(); System.out.println(pass);
} }

socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)的更多相关文章

  1. python 实现统计ftp服务器指定目录下文件夹数目、文件数目及所有文件大小

    本次主要为满足应用方核对上传到ftp服务器的文件是否缺漏. 主要要求:指定目录下,文件夹数目/文件数目/所有文件大小,类似Windows如下功能: 模块介绍: from ftplib import F ...

  2. 获取小众ftp服务器指定目录内容列表

    今天获取小众ftp服务器指定目录内容列表时费劲急了. ///parama url="ftp://x.x.x.x/dir_name" public string GetFTPDir( ...

  3. linux find-在指定目录下查找文件

    推荐:更多Linux 文件查找和比较 命令关注:linux命令大全 find命令用来在指定目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则find ...

  4. PHP 获取指定目录下所有文件(包含子目录)

    PHP 获取指定目录下所有文件(包含子目录) //glob — 寻找与模式匹配的文件路径 $filter_dir = array('CVS', 'templates_c', 'log', 'img', ...

  5. iOS案例:读取指定目录下的文件列表

    // // main.m // 读取指定目录下的文件列表 // // Created by Apple on 15/11/24. // Copyright © 2015年 Apple. All rig ...

  6. PHP 批量获取指定目录下的文件列表(递归,穿透所有子目录)

    //调用 $dir = '/Users/xxx/www'; $exceptFolders = array('view','test'); $exceptFiles = array('BaseContr ...

  7. 文件名命工具类(将指定目录下的文件的type类型的文件,进行重命名,命名后的文件将去掉type)

    import java.io.File; /** * <b>function:</b> 文件命名工具类 * @author hoojo * @createDate 2012-5 ...

  8. linux --> 删除指定目录下所有文件

    删除指定目录下所有文件 代码样例: ///////////////////////////////////////////////////// //Name: DeleteFile //Purpose ...

  9. C# 获取指定目录下所有文件信息

    /// <summary> /// 返回指定目录下所有文件信息 /// </summary> /// <param name="strDirectory&quo ...

随机推荐

  1. hdu6351 2018 Multi-University Training Contest 5 1002 Beautiful Now

    题意: 给出一个十进制数,数位两两可以交换,给出最多能交换多少次,以及交换后的数不能有前缀0,问能形成最小和最大的数 * * * 尝试的思路 贪心,将字符串先排出最大以及最小的情况,然后按一定顺序将对 ...

  2. Win7 VS2015环境编译cegui-0.8.5

    首先是去官网下载源码与依赖库 http://cegui.org.uk/ 然后得提一下,编译DX11版本带Effects11框架的话会有问题,也就是默认情况编译有问题,这是因为VS2015升级后编译器对 ...

  3. Effective C++ 随笔(3)

    条款12: 以对象管理资源 两种只能指针: std:auto_ptr<> 当使用copy操作室,原先的智能指针指向为null std:tr1:share_ptr<int> sp ...

  4. Chapter15 Principles of Metabolic Regulation

    15.1 调节代谢的通路 (1)细胞和有机体维持着动态稳定 调节作用的基因多 2500个 12% 激酶占比多 300个 一个通路受到多方调节 (2)酶的数量和催化活性 可以被调节 反应物的调控 糖酵解 ...

  5. Ng第十三课:聚类(Clustering)

    13.1  无监督学习:简介 13.2 K-均值算法 13.3  优化目标 13.4  随机初始化 13.5  选择聚类数 13.1  无监督学习:简介 在这个视频中,将开始介绍聚类算法.这将是一个激 ...

  6. Ng第二课:单变量线性回归(Linear Regression with One Variable)

    二.单变量线性回归(Linear Regression with One Variable) 2.1  模型表示 2.2  代价函数 2.3  代价函数的直观理解 2.4  梯度下降 2.5  梯度下 ...

  7. 自定义cell的高度

    // //  RootTableViewController.m //  Share // //  Created by lanouhn on 15/1/20. //  Copyright (c) 2 ...

  8. Windows网络编程(C/C++服务器编程)

    Windows服务器网络编程 Linux服务器网络编程

  9. android 首字母迷糊查询 拼音查询 中英文混排查询

    对于这个问题,还没有动手去做,暂且查了查资料,把思路记录下来: 1. 数据库保存拼音+汉字.在插入数据库的时候将这些信息保存下来,将来可以进行首字母模糊查询,拼音查询,中英文混排查询(参考手机通讯录数 ...

  10. Pyenv 安装部署

    Pyenv Pyenv是个多版本Python管理器,可以同时管理多个Python版本共存, 区别于virtualenv. 安装 git clone git://github.com/yyuu/pyen ...