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 ...
随机推荐
- C++航空系统
/* * SHA-256 implementation, Mark 2 * * Copyright (c) 2010,2014 Ilya O. Levin, http://www.literateco ...
- linux系统配置参数修改
一.永久修改主机名修改/etc/sysconfig/network,在里面指定主机名称HOSTNAME=然后执行命令hostname 主机名这个时候可以注销一下系统,再重登录之后就行了. 或者修改/e ...
- Linux查看登录到服务的用户,查看用户的操作已经剔掉干坏事的用户的命令
在工作中,我们有时候会经常的切换用户,有时候会忘记切换到哪个用户了,我们就需要知道当前登录的用户时谁,可以使用: whoami 查看当前登录到系统中的用户有哪些: who 列表中显示,第一列是用户名, ...
- GIS矢量数据化简:一种改进的道格拉斯-普克算法以及C++实现
GIS领域的同志都知道,传统的道格拉斯-普克算法都是递归实现.然而有时候递归的层次太深的话会出现栈溢出的情况.在此,介绍一种非递归的算法. 要将递归算法改为非递归算法,一般情况下分为两种场景.第一种是 ...
- 屏幕抓取程序 (位图DDB的例子)
屏幕抓取程序的意思是将整个屏幕图显示在应用程序的用户区中,等价于截图.对桌面窗口的操作:首先得知道桌面窗口的宽和高,获取宽和高需要利用窗口的设备句柄,而获取设备句柄需要知道窗口句柄,这一系列的连串关系 ...
- 返回结点值为e的二叉树指针
题意为,如果二叉树某结点的值为e(假定是整型二叉树),返回这个结点的指针.初看这道题,联想到二叉树可以很简单的遍历,直接返回这个指针不就行了吗?如下图所示,假如要返回值为3的结点指针: 设计好了一个函 ...
- (转)Memcached深度分析
转自:http://jwen.iteye.com/blog/1123991 memcached是高性能的分布式内存缓存服务器.一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态W ...
- maven依赖管理
maven依赖管理 1.依赖范围 (依赖相当于java中的import 是否需要导入别的jar包) 使用控制依赖与三种classpath(编译期,测试时期,运行时期)的关系 complie ...
- SRM483
250pt 题意:给定一个[0,1)间的实数,一个分母不超过maxDen的分数逼近.. 思路:直接枚举.然后判断. code: #line 7 "BestApproximationDiv1. ...
- JPA Annotation注解
JPA & Hibernate 注解 先说说JPA和Hibernate的关系 JPA(Java Persistence API),是Java EE 5的标准ORM接口,也是ejb3规范的一部分 ...