FTP客戶端

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);
		}
	}
}
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章