java操作ftp實現文件上傳


在工作中經常會操作服務器端的文件,比如需要把一些業務需求生成文件然后上傳到服務器進行存檔,那么如果管理這些文件呢,可以通過遠程連接服務器進行管理,給大家介紹一個遠程服務器連接工具——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 (中文亂碼問題)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM