import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 一个完整功能的FTP客户端类,其实就根据ftp协议,用套接字实现通信
*/
public class FtpClient {
private static final int ALL_INFO = 0;
// private static final int HINT_INFO = 1;
// private static final int ERROR_INFO = 2;
private Socket ftpClient;
private OutputStreamWriter sockWrite;
private InputStreamReader sockRead;
private String strRead;
private int RetCode;
private int igrade = ALL_INFO;
public FtpClient() {
}
public void setInfoGrade(int igrade) {
this.igrade = igrade;
}
/**
* 登录FTP服务器
* @param UserName
* @param Password
* @return
*/
public boolean Login(String UserName, String Password) {
//if (SendCommand(""))
if (SendCommand("USER " + UserName))
if (SendCommand("PASS " + Password))
return true;
return false;
}
/**
* 连接FTP服务器
* @param IP
* @param Port
* @return
*/
public boolean Connect(String IP, int Port) {
try {
ftpClient = new Socket(IP, Port, true);
if (ftpClient.isConnected() == false)
return false;
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
try {
OutputStream os = ftpClient.getOutputStream();
sockWrite = new OutputStreamWriter(os);
InputStream is = ftpClient.getInputStream();
sockRead = new InputStreamReader(is);
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
return true;
}
/**
* 重新发送命令,复位
* @return
*/
public boolean CanResume() {
if (SendCommand("REST 100")) {
PrintInfo("Ftp can Resume to Send!");
return true;
}
PrintInfo("System can not Resume Send!");
return false;
}
/**
* 把FTP服务器上的文件读取到本地
* @param LocalFile 本地文件名
* @param RemFile FTP上的文件名
* @return
*/
public boolean DownFile(String LocalFile, String RemFile) {
//this not user pasv mode to translate the data.
FileOutputStream OutFile;
File DescFile = new File(LocalFile);
long FileLen = 0;
if (CanResume()) {
if (DescFile.exists())
FileLen = DescFile.length();
else
try {
DescFile.deleteOnExit();//delete old the file,then create
// new.
DescFile.createNewFile();
} catch (IOException ex6) {
}
SendCommand("REST " + String.valueOf(FileLen));
}
try {
OutFile = new FileOutputStream(DescFile, true);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
return false;
}
return DownStream(OutFile, RemFile);
}
/**
* 从FTP服务器上读取文件,存为文件输出流,输出
*/
public boolean DownStream(OutputStream outs, String RemFile) {
ServerSocket SvrSocket;
if (!SendCommand("TYPE I"))
return false;
InetAddress Addr = ftpClient.getLocalAddress();
String strAddr = Addr.getHostAddress();
try {
SvrSocket = new ServerSocket(0);
} catch (IOException ex1) {
ex1.printStackTrace();
return false;
}
int RecvPort = SvrSocket.getLocalPort();
strAddr = strAddr.replace('.', ',');
int T1 = RecvPort / 256;
int T2 = RecvPort % 256;
strAddr += "," + String.valueOf(T1) + "," + String.valueOf(T2);
if (!SendCommand("PORT " + strAddr))
return false;
if (!SendCommand("RETR " + RemFile))
return false;
Socket RecvSock;
try {
RecvSock = SvrSocket.accept();
}
catch (IOException ex2) {
ex2.printStackTrace();
return false;
}
InputStream ins;
try {
ins = RecvSock.getInputStream();
byte buff[] = new byte[1024];
int iRead = 1;
while (iRead > 0) {
iRead = ins.read(buff);
if (iRead > 0) {
outs.write(buff, 0, iRead);
}
}
outs.flush();
outs.close();
ins.close();
RecvSock.close();
SvrSocket.close();
} catch (IOException ex3) {
ex3.printStackTrace();
return false;
}
return true;
}
/**
* 关闭FTP连接
*
*/
public void DisConnect() {
try {
SendCommand("QUIT");
sockWrite.close();
sockRead.close();
ftpClient.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
/**
* 发送FTP命令
* @param Cmd
* @return
*/
public boolean SendCommand(String Cmd) {
if (!WriteStr(Cmd + "\r\n"))
return false;
if (!ReadStr())
return false;
if (RetCode >= 400)
return false;
return true;
}
/**
* 通过Socket接收响应值用
* @return
*/
public boolean ReadStr() {
int Len;
char[] ReadBuff = new char[1024];
try {
Len = sockRead.read(ReadBuff);
} catch (IOException ex) {
return false;
}
strRead = String.valueOf(ReadBuff, 0, Len - 2);//off the \r\n
// String sCode = strRead.substring(0, 3);
//前三位为状态码
//修改,如果返回信息分成几次发送回来就有可能没有状态编码
try {
RetCode = Integer.parseInt(strRead.substring(0, 3));
} catch(Exception e) {
RetCode = 0;
}
PrintInfo(strRead);
return strRead.length() > 0;
}
/**
* 通过Socket发送FTP命令用
* @param Write
* @return
*/
public boolean WriteStr(String Write) {
char[] Arr = Write.toCharArray();
try {
sockWrite.write(Arr);
sockWrite.flush();//user the flush,than you can do the next.! OK
PrintInfo(Write);
} catch (IOException ex) {
ex.printStackTrace();
return false;
}
return true;
}
/**
* 把客户端的文件上传到FTP服务器上
* @param LocalFile
* @param RemFile
* @param Pasv
* @return
*/
public boolean PutFile(String LocalFile, String RemFile) {
File LFile = new File(LocalFile);
long Len = LFile.length();
PrintInfo("System Len=" + Len);
FileInputStream ReadFile;
try {
ReadFile = new FileInputStream(LocalFile);
} catch (FileNotFoundException ex) {
ex.printStackTrace();
return false;
}
return PutStream(ReadFile, RemFile);
}
/**
* 把文件流从外部上传到FTP服务器上,存为文件名为RemFile的文件
* @param InStream
* @param RemFile
* @return
*/
public boolean PutStream(InputStream InStream, String RemFile) {
ServerSocket SvrSocket;
if (!SendCommand("TYPE I")){
return false;
}
InetAddress Addr = ftpClient.getLocalAddress();
String strAddr = Addr.getHostAddress();
strAddr = strAddr.replace('.', ',');
try {
SvrSocket = new ServerSocket(0);
} catch (IOException ex1) {
ex1.printStackTrace();
return false;
}
int RecvPort = SvrSocket.getLocalPort();
int T1 = RecvPort / 256;
int T2 = RecvPort % 256;
strAddr += "," + String.valueOf(T1) + "," + String.valueOf(T2);
boolean bport = SendCommand("PORT " + strAddr);
if (!bport){
System.out.println("...........port::"+strAddr+" "+bport);
return false;
}
boolean bstor = SendCommand("STOR " + RemFile);
if (!bstor){
System.out.println("...........STOR::"+RemFile+" "+bstor);
return false;
}
Socket RecvSock;
DataOutputStream writer;
try {
RecvSock = SvrSocket.accept();
writer = new DataOutputStream(RecvSock.getOutputStream());
} catch (IOException ex2) {
ex2.printStackTrace();
return false;
}
byte Buff[] = new byte[1024];
int iRead = 1;
try {
while (iRead > 0) {
iRead = InStream.read(Buff);
if (iRead > 0) {
writer.write(Buff, 0, iRead);
}
}
writer.flush();
writer.close();
InStream.close();
RecvSock.close();
SvrSocket.close();
} catch (IOException e) {
e.printStackTrace();
return false;
}
//if (!SendCommand(""))
//return false;
PrintInfo("up load the file finish!");
return true;
}
/**
* 设置FTP中的路径
* @param Dir
* @return
*/
public boolean SetCurDir(String Dir) {
return SendCommand("CWD " + Dir);
}
/**
* 获取FTP中的当前路径
* @return
*/
public String GetCurDir() {
if (!SendCommand("PWD "))
return null;
else {
int Pos = strRead.indexOf("\"");
int Pos2 = strRead.indexOf("\"", Pos + 1);
String Dir = strRead.substring(Pos + 1, Pos2);
return Dir;
}
}
/**
* 在FTP主目录中创建目录
* @param Dir
* @return
*/
public boolean MkDir(String Dir) {
if (SendCommand("MKD " + Dir))
return true;
else{
System.out.println("........MKDIR FAILD!");
return false;
}
}
/**
* 删除FTP上的目录
* @param Dir
* @return
*/
public boolean RmDir(String Dir) {
if (SendCommand("RMD " + Dir))
return true;
else
return false;
}
/**
* 修改FTP上的文件名
* @param Old
* @param New
* @return
*/
public boolean ReName(String Old, String New) {
if (SendCommand("RNFR " + Old))
return SendCommand("RNTO " + New);
return false;
}
/**
* 删除FTP上的文件
* @param File
* @return
*/
public boolean DelFile(String File) {
return SendCommand("DELE " + File);
}
/**
* 显示FTP主目录上的文件目录和文件名称
* @param ListCmd
* @return
*/
public String[] ListFile(String ListCmd) {
StringBuffer sbDir = new StringBuffer();
ServerSocket SvrSocket;
if (!SendCommand("TYPE A"))
return null;
InetAddress Addr = ftpClient.getLocalAddress();
String strAddr = Addr.getHostAddress();
try {
SvrSocket = new ServerSocket(0);
} catch (IOException ex1) {
ex1.printStackTrace();
return null;
}
int RecvPort = SvrSocket.getLocalPort();
strAddr = strAddr.replace('.', ',');
int T1 = RecvPort / 256;
int T2 = RecvPort % 256;
strAddr += "," + String.valueOf(T1) + "," + String.valueOf(T2);
Socket RecvSock;
if (!SendCommand("PORT " + strAddr))
return null;
SendCommand("LIST " + ListCmd);
try {
RecvSock = SvrSocket.accept();
} catch (IOException ex2) {
ex2.printStackTrace();
return null;
}
DataInputStream dataRead;
try {
dataRead = new DataInputStream(RecvSock.getInputStream());
} catch (IOException ex3) {
ex3.printStackTrace();
return null;
}
byte Buff[] = new byte[1024];
int iRead = 1;
try {
while (iRead > 0) {
iRead = dataRead.read(Buff);
if (iRead > 0) {
sbDir.append(new String(Buff, 0, iRead));
}
}
dataRead.close();
RecvSock.close();
SvrSocket.close();
} catch (IOException ex4) {
ex4.printStackTrace();
return null;
}
if (!SendCommand("NOOP"))
return null;
return (sbDir.toString()).split("\r\n");
}
/**
* 设置信息输出级别
* 0:输出所有信息
* 1:只输出提示信息
* 2:只输出错误信息
*/
private void PrintInfo(String sInfo) {
if (igrade == 0) {
System.out.println(sInfo);
}
}
}