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 ...
随机推荐
- mysql 设置外键 四大属性 CASCADE SET NULL NO ACTION RESTRICT 理解
CASCADE:主表delete.update的时候,从表会delete.update掉关联记录: SET NULL:主表delete.update的时候,从表会将关联记录的外键字段所在列设为null ...
- __getitem__()、__setitem__()与__delitem__()
# 如果想要运用[]取值,可以实现__getitem__() # 想要运用[]设值,可以实现__setitem__() # 若想通过del与[]来删除,可以实现__delitem__() class ...
- boost--asio
1.asio综述 asio的核心类是io_service,它相当于前摄器模式的Proactor角色,在异步模式下发起的I/O操作,需要定义一个用于回调的完成处理函数,当I/O完成时io_service ...
- vue的cli中自定义router
1.安装router npm install vue-router 2.为了方便管理在components同级创建router文件夹 3.在文件夹中创建index.js文件,就是router文件 im ...
- DynamicJson-好用dotnet4的json对象
最近看的书很杂,也深深被ES6的语法感动了,原来javascript可以这么好用.于是重新学习C#4.5.6,发现有一个dynamic就象是一个javascript对象,好玩!且有人写了一个json到 ...
- chrome用type=file获取图片路径并转base64字符串
1 html页面 <div class="col-sm-2" style="height: 200px;margin-top: 14px;"> &l ...
- 网络编程socket、udp
PS:主机字节顺序,个位在低字节上 计算机本身不能通讯,使通过在同一主机或者不同主机内的软件进行数据传输. 套接字socket:套接字socket可以参照文件指针来理解,文件指针是表示对文件打开进行某 ...
- Eclipse怎么全局搜索和替换(整个项目)
我们用Eclipse编程,有时候需要将整个项目的某个字符串替换成其他的.那么我们该怎么操作呢?请接着往下看! 一,我们首先打开Eclipse,单击要替换字符串的项目 二,按下组合键:ctrl + H, ...
- Curl工具的使用
Curl命令可以通过命令行的方式,执行Http请求.在Elasticsearch中有使用的场景,因此这里研究下如何在windows下执行curl命令. 工具下载 在官网处下载工具包:http:// ...
- Windows 8创新之路——样章分享
在电脑里面躺了大约也有半年多的光景了. 在Windows 8.1还有不到一个月的时间里,将这些内容分享出来,也算是对得起自己那段时间的熬夜. 希望大家多提宝贵意见. 谢! 点击标题可浏览SkyDriv ...