ftp是基于tcp协议的传输协议,基本模式就是请求应答模式,对于协议的详细信息可以百度,也可以查看这篇博客 ftp协议。
下面就java语言的tcp来实现该协议的获取文件大小,遍历目录,上传文件,下载文件功能,好了废话不多说上代码。
package com.telrob.ftp;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class DataConnect {
private Socket dataSocket=null;
private InputStream dataIn=null;
private OutputStream dataOut=null;
public Socket getDataSocket() {
return dataSocket;
}
public void setDataSocket(Socket dataSocket) {
this.dataSocket = dataSocket;
}
public InputStream getDataIn() {
return dataIn;
}
public void setDataIn(InputStream dataIn) {
this.dataIn = dataIn;
}
public DataConnect(Socket dataSocket, InputStream dataIn, OutputStream dataOut) {
super();
this.dataSocket = dataSocket;
this.dataIn = dataIn;
this.dataOut = dataOut;
}
public OutputStream getDataOut() {
return dataOut;
}
public void setDataOut(OutputStream dataOut) {
this.dataOut = dataOut;
}
public void destoryInput() throws IOException {
dataSocket.close();
dataIn.close();
}
public void destoryOutput() throws IOException {
dataSocket.close();
dataOut.close();
}
}
package com.telrob.ftp;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
/**
* ftp类
* @author wh
*
*/
public class MFtp {
private String ip;
private String userName;
private String password;
private int port=21;
private String line;
//命令端口
private Socket cmdSocket=null;
private OutputStream cmdOut=null;
private BufferedReader cmdBr=null;
//数据端口
private boolean debug=false;
public MFtp(String ip,String userName,String password) {
this.ip=ip;
this.userName=userName;
this.password=password;
}
public MFtp(String ip,String userName,String password,int port) {
this.ip=ip;
this.userName=userName;
this.password=password;
this.port=port;
}
/**
* 设置debug模式
* @param d
*/
public void setDebug(boolean d) {
this.debug=d;
}
/**
* 创建连接
* @return
* @throws Exception
*/
public boolean createConnect() throws Exception {
cmdSocket=new Socket(ip,port);
cmdOut=cmdSocket.getOutputStream();
cmdBr=new BufferedReader(new InputStreamReader(cmdSocket.getInputStream()));
line=cmdBr.readLine();
line=sendCmd("USER "+userName+"\r\n");
line=sendCmd("PASS "+password+"\r\n");
if(line.startsWith("230 User logged in")) {
return true;
}
return false;
}
/**
* 发送命令
* @param cmd
* @return
* @throws Exception
*/
public String sendCmd(String cmd) throws Exception {
if(cmdSocket!=null) {
debugger("cmd: ["+cmd+"]");
cmdOut.write(cmd.getBytes("GBK"));
String line=cmdBr.readLine();
debugger("response: ["+line+"]");
return line;
}else {
throw new Exception("创建连接失败!");
}
}
/**
* 获取文件大小
* @param name
* @return
*/
public long getFileSize(String path) {
try {
line=sendCmd("SIZE "+path+"\r\n");
if(line!=null&&!line.equals("")) {
String[]sz=line.split(" ");
return Long.parseLong(sz[1]);
}
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public boolean uploadFile(String path,FileInputStream in) throws Exception {
DataConnect dc=getDataStream(2);
try {
String line=sendCmd("STOR "+path+"\r\n");
if(line.startsWith("125")) {
OutputStream out=dc.getDataOut();
int len=0;
byte[]bb=new byte[1024*4];
while((len=in.read(bb))>0) {
out.write(bb,0,len);
}
return true;
}else {
return false;
}
}catch(Exception e) {
e.printStackTrace();
}finally {
dc.destoryOutput();
}
return false;
}
/***
* 下载文件
* @param path 文件路径
* @param fileout 文件输出流
* @return
* @throws Exception
*/
public boolean downLoadFile(String path,OutputStream fileout) throws Exception {
DataConnect dc=getDataStream(1);
InputStream in=dc.getDataIn();
try {
String line=sendCmd("RETR "+path+"\r\n");
if(line.startsWith("150")||line.startsWith("125")) {
int len=0;
byte[]bb=new byte[1024*4];
while((len=in.read(bb))>0) {
fileout.write(bb,0,len);
}
}
line = cmdBr.readLine();
if(line.contains("Transfer complete")) {
return true;
}else {
return false;
}
}catch(Exception e){
e.printStackTrace();
}finally {
dc.destoryInput();
}
return false;
}
/**
* 列出目录对应的文件或者文件夹
* @param path
* @return
* @throws Exception
*/
public List<MFtpFile> listFile(String path) throws Exception{
List<MFtpFile>fileList=new ArrayList<MFtpFile>();
DataConnect dc=getDataStream(1);
InputStream in=dc.getDataIn();
sendCmd("LIST "+path+"\r\n");
StringBuffer buffer=new StringBuffer();
int len;
byte[]bb=new byte[1024];
while((len=in.read(bb))>0) {
buffer.append(new String(bb,0,len,"GBK"));
}
String line=cmdBr.readLine();
String relult=buffer.toString();
String[]item=relult.split("\r\n");
for(String d:item) {
if(d.equals("")) {
continue;
}
fileList.add(new MFtpFile(d,path));
}
dc.destoryInput();
return fileList;
}
/***
* 获取数据流
* @param type 1输入流 2,输出流
* @return
* @throws Exception
*/
private DataConnect getDataStream(int type) throws Exception {
line=sendCmd("PASV\r\n");
String[]ll=line.split(",");
String[]pp=ll[5].split("\\)");
int port=Integer.parseInt(pp[0]);
int tp=port;
int basep=Integer.parseInt(ll[4]);
//返回的第一个数字*256+第二个数字
port=basep*256+port;
Socket dataSocket=new Socket(ip, port);
if(type==1) {
InputStream dataIn=dataSocket.getInputStream();
return new DataConnect(dataSocket,dataIn,null);
}else {
OutputStream out=dataSocket.getOutputStream();
return new DataConnect(dataSocket,null,out);
}
}
/**
* 调试
* @param str
*/
private void debugger(String str) {
if(debug) {
str=str.replaceAll("\r\n", "");
System.out.println(str);
}
}
}
package com.telrob.ftp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
/**
* 封装ftp文件对象
* @author wh
*
*/
public class MFtpFile {
//是否为目录
private boolean isDirectory=false;
//目录名称
private String fileName;
private String absoluteName;
//文件大小
private long size;
//最后一次修改时间
private Date time;
public MFtpFile() {}
public MFtpFile(String line,String base) {
//需要对协议中的一行进行解析 格式如下
// 12-01-17 02:47PM <DIR> code
// 03-08-18 05:40PM 85660682 Dev-Cpp.zip
List<String>list=parse(line);
if(list!=null&&list.size()==4) {
SimpleDateFormat fmt=new SimpleDateFormat("MM-dd-yy hh:mma",Locale.US);
try {
String tm=list.get(0)+" "+list.get(1);
time=fmt.parse(list.get(0)+" "+list.get(1));
if(list.get(2).contains("DIR")) {
isDirectory=true;
size=0;
}else {
isDirectory=false;
size=Long.parseLong(list.get(2));
}
fileName=list.get(3);
absoluteName=base+"/"+list.get(3);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
public boolean isDirectory() {
return isDirectory;
}
public void setDirectory(boolean isDirectory) {
this.isDirectory = isDirectory;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
public Date getTime() {
return time;
}
public void setTime(Date time) {
this.time = time;
}
public String getAbsoluteName() {
return absoluteName;
}
public void setAbsoluteName(String absoluteName) {
this.absoluteName = absoluteName;
}
private List<String>parse(String ss){
List<String>list=new ArrayList<String>();
//03-08-18 05:40PM 85660682 Dev-Cpp.zip
String[]items=ss.split(" ");
int i=0;
for(String s:items) {
if(!s.equals("")) {
list.add(s);
i++;
}
if(i==3) {
break;
}
}
String item2=list.get(2);
int last=ss.indexOf(item2)+item2.length();
String names=ss.substring(last, ss.length());
list.add(names.trim());
return list;
}
}
下面试测试类
package com.telrob.ftp;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
public class Test2 {
public static void main(String[] args) throws Exception {
MFtp ftp=new MFtp("192.168.9.111", "zhang", "123456");
String line="";
ftp.setDebug(true);
if(ftp.createConnect()) {
long size=ftp.getFileSize("apache-activemq-5.15.0-bin.zip");
FileOutputStream fout=new FileOutputStream("test.zip");
ftp.downLoadFile("apache-activemq-5.15.0-bin.zip", fout);
//ftp.uploadFile("dd.jpeg",new FileInputStream("dd.jpeg"));
fout.close();
list(ftp,"");
}
}
static int total=0;
public static void list(MFtp ftp,String path) throws Exception {
List<MFtpFile> list=ftp.listFile(path);
if(list!=null&&list.size()>0) {
for(MFtpFile mf:list) {
//System.out.println("total:"+total++);
if(mf.isDirectory()) {
list(ftp,mf.getAbsoluteName());
System.out.println("@@dir:"+mf.getAbsoluteName());
}else {
System.out.println("##file:"+mf.getAbsoluteName());
}
}
}
}
}