socket实现两台FTP服务器指定目录下的文件转移(不依赖第三方jar包)
通过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包)的更多相关文章
- python 实现统计ftp服务器指定目录下文件夹数目、文件数目及所有文件大小
本次主要为满足应用方核对上传到ftp服务器的文件是否缺漏. 主要要求:指定目录下,文件夹数目/文件数目/所有文件大小,类似Windows如下功能: 模块介绍: from ftplib import F ...
- 获取小众ftp服务器指定目录内容列表
今天获取小众ftp服务器指定目录内容列表时费劲急了. ///parama url="ftp://x.x.x.x/dir_name" public string GetFTPDir( ...
- linux find-在指定目录下查找文件
推荐:更多Linux 文件查找和比较 命令关注:linux命令大全 find命令用来在指定目录下查找文件.任何位于参数之前的字符串都将被视为欲查找的目录名.如果使用该命令时,不设置任何参数,则find ...
- PHP 获取指定目录下所有文件(包含子目录)
PHP 获取指定目录下所有文件(包含子目录) //glob — 寻找与模式匹配的文件路径 $filter_dir = array('CVS', 'templates_c', 'log', 'img', ...
- iOS案例:读取指定目录下的文件列表
// // main.m // 读取指定目录下的文件列表 // // Created by Apple on 15/11/24. // Copyright © 2015年 Apple. All rig ...
- PHP 批量获取指定目录下的文件列表(递归,穿透所有子目录)
//调用 $dir = '/Users/xxx/www'; $exceptFolders = array('view','test'); $exceptFiles = array('BaseContr ...
- 文件名命工具类(将指定目录下的文件的type类型的文件,进行重命名,命名后的文件将去掉type)
import java.io.File; /** * <b>function:</b> 文件命名工具类 * @author hoojo * @createDate 2012-5 ...
- linux --> 删除指定目录下所有文件
删除指定目录下所有文件 代码样例: ///////////////////////////////////////////////////// //Name: DeleteFile //Purpose ...
- C# 获取指定目录下所有文件信息
/// <summary> /// 返回指定目录下所有文件信息 /// </summary> /// <param name="strDirectory&quo ...
随机推荐
- 威伦TK6070iQ触摸屏的使用
A.TK6070iQ只支持U盘互相倒腾. TK6070iQ有2个串口Com1 (232) Com2 (485) U盘上传 需要选择COM2(485),因为上传后是PLC与触摸屏通过485通讯,协议选s ...
- mac环境下配置nginx
1.建议使用homebrew安装(ruby安装 brew install ruby) ruby -e "$(curl -fsSL https://raw.githubusercont ...
- poj 1328 Radar Installation(贪心+快排)
Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea i ...
- window下切换python
自己的win10装了2.7和3.6版本的python.本不想装2.7的,但node.js的C++的编译居然用到2.X的python,没法子就装了2.7.那怎么切换呢? 为了方便使用,我在系统的path ...
- android include使用[转]
需要包含的xml文件,我这里就放了一个Button按钮: btn.xml: <?xml version="1.0" encoding="utf-8"?&g ...
- 阿里云服务器 OSS的使用限制
使用限制 更新时间:2019-02-12 16:50:27 编辑 · OSS的使用限制及性能指标如下: 限制项 说明 归档存储 已经存储的数据从冷冻状态恢复到可读取状态需要 1 分钟的等待时间. ...
- POJ3045--Cow Acrobats(theory proving)
Farmer John's N (1 <= N <= 50,000) cows (numbered 1..N) are planning to run away and join the ...
- chrome常用小插件
1.广告终结者 (去广告) 2.adsafe2.0.1 (去广告) 3.Infinity New Tab ( ...
- win10专业版激活工具很不错!
下载链接: http://www.yishimei.cn/?=0xj20
- 2.mongodb可视化工具
(1)去robomongo官方网址下载,官网地址(https://robomongo.org/)选择相应的版本. (2) tar -xzf robo3t-1.2.1-linux-x86_64-3e50 ...