在工作中經常會操作服務器端的文件,比如需要把一些業務需求生成文件然后上傳到服務器進行存檔,那么如果管理這些文件呢,可以通過遠程連接服務器進行管理,給大家介紹一個遠程服務器連接工具——FTP客戶端-IIS7服務器管理工具
作為FTP客戶端,它支持批量管理ftp站點。定時上傳和定時下載,定時備份,且操作簡潔。同時iis7服務器管理工具還是vnc客戶端。並且支持批量管理管理windows及linux服務器、vps。讓服務器真正實現了一站式管理,真的是非常方便。
下載地址:http://fwqglgj.iis7.net/cp/ftp/?tscc-zc
ftp客戶端工具部分介紹圖如下所示:
前段時間寫過一個ftp同步信息的需求,意思就是將我們項目的iptv設備的同步信息定時生成一個csv文件並且上傳到對方的ftp服務器上。第一次做這樣的需求,用java操作ftp服務器,包括連接登錄ftp服務器,將內容寫到文件中並且上傳到ftp服務器上,最后斷開連接。
同步信息bean
public class FtpIptvBean {
private String region ;//所屬分公司
private String stbid;//機頂盒標識 終端SN號
private String deviceVendorName;//設備廠商
private String terminalModel;//終端型號
private String mangerDate;//設備入庫時間 yyyyMMddHHmmss
private String attribution;//政企/家客 在設備表中用type表示 1是家客,2 是政企(集客)
//setter/getter
}
信息同步類TerminalTestTask
//導入與ftp相關的包
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
//io流相關的包
import java.io.*;
public class TerminalTestTask {
private FTPClient ftpClient = null;
File file = new File(fileName);
//創建文件
FtpConnetUtil.createFile(file);
//需要寫入文件的內容
List<FtpIptvBean> contentList=terminalTestTaskService.selectIptvInfo();
//省略for循環解析,將要存入文件的字段拼接起來
String contentStr =contentList.get(i).getRegion()+"|"+contentList.get(i).getStbid()+"|"+contentList.get(i).getTerminalModel()+"|"+contentList.get(i).getDeviceVendorName()+"|"+intime+"|"+attribution;
//向文件中寫入內容並且換行
FtpConnetUtil.fileChaseFWNewLine(fileName, contentStr);
//通過配置文件讀取ftp有關配置信息
Properties properties = FtpConnetUtil.getConnet();
String ftpurl = properties.getProperty("ftpiptvurl");
String ftpport = properties.getProperty("ftpiptvport");
String ftpusername = properties.getProperty("ftpiptvusername");
String ftppassword = properties.getProperty("ftpiptvpassword");
//服務器文件地址
String ftppath = properties.getProperty("ftpiptvpath");
//創建一個FTPClient 對象
ftpClient = new FTPClient();
//連接ftp
ftpClient.connect(ftpurl,Integer.parseInt(ftpport));
//登錄ftp服務器
ftpClient.login(ftpusername, ftppassword);
//創建文件輸入流
FileInputStream input = null;
//在ftp服務器上新建一個目錄用於存放上傳的文件
ftpClient.makeDirectory(ftppath);
//修改當前工作目錄
ftpClient.changeWorkingDirectory(ftppath);
/*調用FTPClient.enterLocalPassiveMode();這個方法采用的是被動模式連接,就是每次數據連接之前,ftp client告訴ftp server開通一個端口來傳輸數據。*/
ftpClient.enterLocalPassiveMode();
// FTP的傳輸有兩種方式:ASCII傳輸模式和二進制數據傳輸模式。
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
//把文件內容寫入流中
input = new FileInputStream(file);
//將流寫入服務器
flag = ftpClient.storeFile(file.getName(), input);
//文件上傳到ftp服務器之后就斷開連接退出
ftpClient.logout();
//執行關閉流操作
}
涉及到的ftp工具類
public class FtpConnetUtil {
/**
* 創建文件
* @param fileName
* @return
*/
public static boolean createFile(File fileName)throws Exception{
try{
if(!fileName.exists()){
fileName.createNewFile();
}
}catch(Exception e){
e.printStackTrace();
}
return true;
}
/**
* 寫入文件,追加寫入並且換行
* @param filePath
* @param content
*/
public static void fileChaseFWNewLine(String filePath, String content) {
try {
//構造函數中的第二個參數true表示以追加形式寫文件
FileWriter fw = new FileWriter(filePath,true);
fw.write(content);
fw.write("\r\n"); //表示換行
fw.close();
} catch (IOException e) {
System.out.println("文件寫入失敗!" + e);
}
}
//讀取配置文件
public static Properties getConnet() throws Exception{
Properties properties = new Properties();
InputStream is = FtpConnetUtil.class.getResourceAsStream("ftp.properties");
properties.load(is);
is.close();
return properties;
}
/**
* 獲取FTPClient對象
* @param ftpHost FTP主機服務器
* @param ftpPassword FTP 登錄密碼
* @param ftpUserName FTP登錄用戶名
* @param ftpPort FTP端口 默認為21
* @return
*/
public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
String ftpPassword, int ftpPort) {
FTPClient ftpClient = null;
try {
ftpClient = new FTPClient();
ftpClient.connect(ftpHost, ftpPort);// 連接FTP服務器
ftpClient.login(ftpUserName, ftpPassword);// 登陸FTP服務器
if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.info("未連接到FTP,用戶名或密碼錯誤。");
ftpClient.disconnect();
} else {
logger.info("FTP連接成功。");
}
} catch (SocketException e) {
e.printStackTrace();
logger.info("FTP的IP地址可能錯誤,請正確配置。");
} catch (IOException e) {
e.printStackTrace();
logger.info("FTP的端口錯誤,請正確配置。");
}
return ftpClient;
}
}
總結:
ftp連接時的模式:主動模式和被動模式,以及java連接ftp時的模式設置問題。
(1) PORT(主動模式)
PORT中文稱為主動模式,工作的原理: FTP客戶端連接到FTP服務器的21端口,發送用戶名和密碼登錄,登錄成功后要list列表或者讀取數據時,客戶端隨機開放一個端口(1024以上),發送 PORT命令到FTP服務器,告訴服務器客戶端采用主動模式並開放端口;FTP服務器收到PORT主動模式命令和端口號后,通過服務器的20端口和客戶端開放的端口連接,發送數據。
(2) PASV(被動模式)
PASV是Passive的縮寫,中文成為被動模式,工作原理:FTP客戶端連接到FTP服務器的21端口,發送用戶名和密碼登錄,登錄成功后要list列表或者讀取數據時,發送PASV命令到FTP服務器, 服務器在本地隨機開放一個端口(1024以上),然后把開放的端口告訴客戶端, 客戶端再連接到服務器開放的端口進行數據傳輸。
(3)兩種模式的比較
主動模式:客戶端開放端口給服務端用;被動模式:服務端開放端口給客戶端用。由於很多客戶端端口在防火牆內,開放端口給服務器端用比較困難。所以用被動模式的時候比較多。
(4)java中,內網用被動模式 ,外網連接時用主動模式。
FTPClient ftpClient = new FTPClient();
ftpClient.connect(url, port);
//主動模式
//ftpClient.enterLocalActiveMode();
ftpClient.enterLocalPassiveMode(); //被動模式
ftpClient.setControlEncoding("UTF-8");
ftpClient.changeWorkingDirectory(path);
參考博文:
(1) https://www.cnblogs.com/huhaoshida/p/5412615.html
(2) https://blog.csdn.net/weixin_44706512/article/details/89281792
(3) https://blog.csdn.net/afei3418/article/details/54375858
(4) https://blog.csdn.net/liquantong/article/details/74080095 (中文亂碼問題)