Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 欧美一区二区激情视频,欧美色图亚洲激情,韩国一级免费视频

          整合營銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          如何使用FTP軟件連接WordPress網(wǎng)站

          文包含F(xiàn)TP軟件介紹、下載、不同主機(jī)創(chuàng)建FTP賬號的方法、以及連接WordPress網(wǎng)站的詳細(xì)步驟。

          本文原文首發(fā)于:https://loyseo.com/wordpress-ftp-access-guide/

          什么用FTP軟件

          FTP是文件傳輸協(xié)議,F(xiàn)TP軟件就是用來傳輸文件用的,本文將使用的免費(fèi)FTP軟件FileZilla。

          用FTP軟件連接WordPress網(wǎng)站能干些啥?

          用FTP軟件連接WordPress網(wǎng)站,就是用FTP軟件管理WordPress網(wǎng)站的文件,譬如上傳文件、刪除文件、修改文件、下載文件等等,利用它還能解決一些問題,譬如:

          • 由于安裝某個插件、或插件沖突、或bug、或忘記后臺地址等等,導(dǎo)致后臺進(jìn)不去時,可進(jìn)入FTP,將指定插件文件夾或插件的總文件夾(Plugins)的名字改一下,等于禁用了這個插件或所有插件,這樣就能登錄后臺了。

          • 安裝較多或較大插件或主題時,直接可以在FTP里一次性上傳

          如何使用FTP軟件FileZilla連接Wordpress網(wǎng)站

          Step1:下載并安裝FileZilla

          點(diǎn)擊FileZilla前往下載;若是無法安裝exe客戶端,可以直接下載免安裝的zip包,解壓后直接點(diǎn)擊文件夾內(nèi)的filezilla運(yùn)行。

          Step2:登錄網(wǎng)站主機(jī)商,新建或獲取FTP賬號及密碼

          以外貿(mào)網(wǎng)站建設(shè)常用主機(jī)SiteGround為示例,我們接下來講解如何在SiteGround創(chuàng)建FTP賬號。

          在Siteground主機(jī)中創(chuàng)建FTP賬號

          1. 在網(wǎng)站的sitetools,進(jìn)入Site》 FTP accounts頁面

          2. 輸入賬號及密碼

          3. 點(diǎn)擊Create就可以成功創(chuàng)建賬號

          4. 記住右邊的FTP hostname和 Port,待會在FTP軟件中需要輸入

          在Cpanel面板中創(chuàng)建FTP賬號

          如果你買的主機(jī)是用的Cpanel面板(譬如Chemicloud、GreenGeeks),就按照下面的方法創(chuàng)建FTP賬號

          首先在Cpanel中找到FTP Accounts并進(jìn)入

          接下來輸入賬號信息,如下圖所示,需要注意的是directory,系統(tǒng)會為你默認(rèn)生成內(nèi)容,但你需要將它們?nèi)縿h除保持為空,或輸入public_html;如保持為空,則這個FTP賬號能訪問你的主機(jī)下所有文件夾,不限于網(wǎng)站文件夾,還有備份存放的文件夾等等;若輸入public_html,則這個FTP賬號能訪問你的主機(jī)下的網(wǎng)站文件夾。

          賬號創(chuàng)建完成后,在該頁面下方會顯示賬號列表,其中包含了修改密碼、查看FTP配置和下載客戶端功能,如下圖所示,你可以點(diǎn)擊configure FTP client查看主機(jī)地址及端口(port:21)

          在寶塔面板中創(chuàng)建FTP賬號

          首先你需要確認(rèn)已經(jīng)安裝了下圖中所示的Pure-Ftpd 1.0.49軟件,若沒有安裝,請?jiān)谲浖痰曛姓业剿Ⅻc(diǎn)擊安裝。

          接下來,按如下步驟創(chuàng)建FTP賬號

          1. 點(diǎn)擊FTP菜單

          2. 點(diǎn)擊添加FTP按鈕

          3. 在彈出層中填寫用戶名

          4. 填寫密碼

          5. 選擇FTP需要連接的網(wǎng)站的文件夾

          6. 點(diǎn)擊提交按鈕即可

          注意上圖中,在添加FTP上方,有個當(dāng)前FTP地址,其中的IP便是FTP軟件中所需輸入的主機(jī)地址,端口號默認(rèn)是21

          Step3:在FTP軟件中連接網(wǎng)站主機(jī)

          1. 打開FileZilla,點(diǎn)擊左上角的主機(jī)圖標(biāo)

          2. 在彈出層中,點(diǎn)擊新站點(diǎn)

          3. 設(shè)置新站點(diǎn)名稱

          4. 輸入主機(jī)域名,若主機(jī)沒有提供FTP域名,則輸入IP;端口號默認(rèn)為空即表示為21

          5. 填寫FTP賬號的用戶名和密碼

          6. 點(diǎn)擊連接按鈕

          若連接過程中出現(xiàn)如下提示,直接點(diǎn)擊確定按鈕即可

          當(dāng)連接成功后,你將看到如下界面,圖中1是你的電腦,2是網(wǎng)站主機(jī),你可以通過鼠標(biāo)拖拽文件夾實(shí)現(xiàn)文件的下載或上傳,從右側(cè)拖拽到左側(cè)就是下載;從左側(cè)拖拽到右側(cè)就是上傳,注意拖拽前定好文件存儲或上傳的目錄。

          除了拖拽的方法,你也可以選擇文件后,點(diǎn)擊右鍵展開操作項(xiàng),譬如若是需要下載備份,按下圖所示

          1. 在左側(cè)選擇需要存放備份的文件夾

          2. 在右側(cè)點(diǎn)選備份所在的文件夾

          3. 在文件夾內(nèi)找到備份,右鍵選擇下載

          4. 文件正在下載并顯示進(jìn)度,若網(wǎng)絡(luò)中斷,也可以繼續(xù)下載并選擇斷點(diǎn)續(xù)傳

          本文原文由LOYSEO.COM發(fā)布,LOYSEO專注于WordPress外貿(mào)網(wǎng)站建設(shè)教程、Elementor教程。

          務(wù):利用FTP上傳.html文件

          描述:利用FTP軟件上傳編寫好的index.html文件,并能通過空間服務(wù)商提供的IP地址或者域名進(jìn)行訪問。

          王岑看著自己的勞動成果,非常滿意,他甚至不停的改變網(wǎng)頁的內(nèi)容,差點(diǎn)就要寫一篇文章了。王岑心里美滋滋的,心想原來做網(wǎng)站也不難嘛,下面就是把他寫好的頁面上傳到陳輝所說的空間了。

          于是他又拿出了那張鄒巴巴的小紙條,他發(fā)現(xiàn)上面只寫了三句話,背面還寫了一個400的客服電話。

          FTP地址:180.186.72.213

          FTP賬戶:koudefu

          FTP密碼:123456

          王岑從陳輝那里知道,這個電話是提供24小時服務(wù)的,如果在服務(wù)器上傳時有什么不明白的地方就可以打電話咨詢。于是王岑就撥起了這個客服電話,他現(xiàn)在哪里是有什么不明白而是全不明白。經(jīng)過一連串的機(jī)器人選項(xiàng)后后王岑直接撥0找到的了人工服務(wù)。就聽王岑開門見山的問道:“你好!我的網(wǎng)站已經(jīng)做好了,請問要怎么樣才能上傳到我的服務(wù)器上呢?”

          語落,就聽一個非常甜美的聲音耐心的說道:“把文件上傳到服務(wù)器的方法很多。大家最常用的就是用FTP方式上傳。一般在您購買了我們的空間后,我們都會給你提供一個FTP的IP地址、賬戶名和密碼。然后您在網(wǎng)上下載一個FTP客戶端軟件就可以了,比如flashfxp就挺好。”

          “FTP是什么?”,王岑有些不解的問道。

          “FTP是英文(FileTransferProtocol)文件傳輸協(xié)議的意思,flashfxp就是利用這個協(xié)議來傳輸文件的。”客服仍舊耐心解釋道。

          王岑英文不是很好,所以沒有聽清FTP的英文說明,不過他卻記住了FTP是文件傳輸協(xié)議的意思。等他回過神時,就聽電話里的客服繼續(xù)解釋道:“flashfxp的使用也挺簡單。安裝好后,在菜單欄依次點(diǎn)擊【站點(diǎn)】-【站點(diǎn)管理器】-【新建站點(diǎn)】按鈕創(chuàng)建一個新站點(diǎn)就可以了。在新建站點(diǎn)窗口文本框中輸入我們給您的IP地址、賬戶名和密碼,然后點(diǎn)擊【連接】按鈕后就可以正常使用了。”

          王岑不知不覺的點(diǎn)了點(diǎn)頭,嗯了一聲繼續(xù)問道:“用你說的這個什么flashfxp就可以上傳我的代碼了對吧?”

          “對,flashfxp、flashfxp不僅能夠上傳文件,還可以直接刪除啊、編輯啊、替換啊文件等等。一般flashfxp軟件左邊窗口就是您本地的文件目錄,右邊窗口則是服務(wù)器文件目錄,您只需把本地的文件直接拖拽到右邊服務(wù)器的目錄上就可以了。當(dāng)您把剛才寫好index.html上傳到您的服務(wù)器(也叫空間)后,再次用我們給您提供的域名刷新你的網(wǎng)站就可以了。”

          王岑一邊聽著客服的耐心解答,一邊按照客服的要求進(jìn)行操作,中間偶爾遇到一點(diǎn)兒意外,客服也都一一進(jìn)行了的指導(dǎo)。

          隨后,經(jīng)過幾分鐘的軟件下載、安裝和站點(diǎn)設(shè)置后,文件輕輕一拖,果然成功上傳了,這讓王岑很是高興。Flashfxp添加站點(diǎn)如下圖所示:

          Flashfxp

          情提示:文章比較長,方法都是有一層層封裝的,閱讀需要按照文章順序閱讀

          首先寫一個簡單的FTP工具類,先實(shí)現(xiàn)最基本的文件上傳,下載,刪除,拷貝功能。這里操作FTP是用的commons-net-3.3.jar中的org.apache.commons.net.ftp中的對象

          package com.wzh.config.utils;
          
          import org.apache.commons.net.ftp.FTP;
          import org.apache.commons.net.ftp.FTPClient;
          import org.apache.commons.net.ftp.FTPFile;
          import org.apache.commons.net.ftp.FTPReply;
          import org.apache.log4j.Logger;
          
          import java.io.*;
          import java.nio.charset.Charset;
          import java.util.ArrayList;
          import java.util.List;
          
          /**
           * @author wzh
           * @create 2018-05-06 23:03
           * @desc ${操作FTP文件工具類}
           **/
          public class FtpUtils {
          
              private static Logger log = Logger.getLogger(FtpUtils.class);
          
              //本地編碼集對象
              private static String encode = Charset.defaultCharset().toString();
          
              // FTP編碼為iso-8859-1
              private static final String SERVER_CHARSET = "ISO-8859-1";
          
              //FTP下載時讀入內(nèi)存的大小
              private static final int BUFFER_SIZE = 1024000;
          
          
              /**
               * 獲取FTP連接對象,連接FTP成功返回FTP對象,
               * 連接FTP失敗超過最大次數(shù)返回null,使用前請判斷是否為空
               * @param ftpHost 服務(wù)器ip
               * @param ftpPort 服務(wù)器端口
               * @param ftpUserName 用戶名
               * @param ftpPassword 密碼
               * @return FTPClient FTP連接對象
               */
              public static FTPClient getFTPClient(String ftpHost, int ftpPort, String ftpUserName, String ftpPassword) {
          
                  //FTP連接對象
                  FTPClient ftpClient = null;
          
                  try
                  {
                      ftpClient = new FTPClient();
                      //設(shè)置FTP服務(wù)器IP和端口
                      ftpClient.connect(ftpHost,ftpPort);
                      //設(shè)置超時時間,毫秒
                      ftpClient.setConnectTimeout(50000);
                      //登錄FTP
                      ftpClient.login(ftpUserName,ftpPassword);
          
                      //設(shè)置被動傳輸模式
                      ftpClient.enterLocalPassiveMode();
                      //ftpClient.enterRemotePassiveMode();
                      //二進(jìn)制傳輸
                      ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
                      //設(shè)置讀入內(nèi)存文件大小
                      ftpClient.setBufferSize(BUFFER_SIZE);
          
                      //獲取FTP連接狀態(tài)碼 ,大于等于200 小于300狀態(tài)碼表示連接正常
                      int connectState = ftpClient.getReplyCode();
          
                      //連接失敗重試
                      int reNum = 0;
                      while (!FTPReply.isPositiveCompletion(connectState)
                              && reNum < 3)
                      {
                          ftpClient.disconnect();
                          ++reNum;
                          ftpClient.login(ftpUserName,ftpPassword);
          
                      }
                      if (reNum < 3) {
          
                          log.info("FTP連接成功");
          
                      } else {
                          ftpClient = null;
                          log.error("FTP連接失敗");
                      }
          
                  } catch (Exception e)
                  {
          
                      log.error(e.getMessage(), e);
                  }
          
                  return ftpClient;
              }
          
              /**
               *斷開FTP
               * @param ftpClient fpt連接對象
               */
              public static void closeFTP(FTPClient ftpClient) {
          
                  if (null != ftpClient) {
                      try {
                          //登出FTP
                          ftpClient.disconnect();
                          log.info("登出FTP成功");
                      } catch (IOException e) {
                          log.error(e.getMessage(), e);
                      } finally {
                          try {
                              //斷開FTP
                              ftpClient.disconnect();
                              log.info("斷開FTP成功");
                          } catch (IOException e) {
                              log.error(e.getMessage(), e);
                          }
                      }
          
                  }
              }
          
          
              /**
               * 根據(jù)FTP編碼集轉(zhuǎn)換文件路徑,防止中文亂碼,并設(shè)置FTP連接的編碼集
               * @param ftpClient FTP連接對象
               * @param path 文件路徑
               * @return 轉(zhuǎn)碼后的文件路徑
               */
              public static String changeEncode(FTPClient ftpClient,String path) throws IOException
              {
                  synchronized (encode)
                  {
                      int status = ftpClient.sendCommand("OPTS UTF8","ON");
                      //判斷FTP服務(wù)器是否支持UTF -8,支持使用UTF-8 否則使用本地編碼集
                      if(FTPReply.isPositiveCompletion(status))
                      {
                          encode = "UTF-8";
                      }
          
                      log.info("FTP使用編碼集:" + encode);
          
                      ftpClient.setControlEncoding(encode);
                      path = new String(path.getBytes(encode),SERVER_CHARSET);
                  }
          
                  return path;
              }
          
              /**
               * 獲取文件后綴
               * @param fileName 文件名或文件全路徑
               * @return 文件后綴
               */
              public static String getSuffix(String fileName)
              {
                  String suffix = "";
          
                  int index = fileName.lastIndexOf(".");
                  if(index != -1)
                  {
                      suffix = fileName.substring(index);
                      log.info("獲取文件后綴名成功,文件名:" + fileName + " 后綴名:" + suffix);
                  }else{
                      log.warn("獲取文件后綴名失敗,文件名" + fileName);
                  }
                  return suffix;
              }
          
              /**
               * 獲取FTP指定文件大小
               * @param ftpClient ftp連接對象
               * @param fileName ftp文件服務(wù)器路徑 如:/public/file/xxx.text
               * @return 文件大小,獲取失敗返回-1
               */
              public static Long getFtpFileSize(FTPClient ftpClient, String fileName)
              {
                  FTPFile[] files = null;
                  Long fileSize = -1L;
                  try {
          
                      files = ftpClient.listFiles(changeEncode(ftpClient,fileName));
          
                      //因?yàn)橹付司唧w的文件名,這里只取數(shù)組0位
                      if (null != files && files.length > 0)
                      {
                          log.info("文件個數(shù):" + files.length + " 文件名:" +
                                  files[0].getName() + " 文件大小:" + files[0].getSize());
          
                          fileSize = files[0].getSize();
                      }
                  } catch (IOException e) {
          
                      fileSize = 1L;
                      log.error(e.getMessage(),e);
                  }
          
                  return fileSize;
              }
          
              /**
               *下載FTP上指定文件路徑文件
               * @param ftpClient FTP連接對象
               * @param filePath 文件路徑+文件名 例如:/public/file/a.txt
               * @param downPath 下載文件保存的路徑
               * @param newFileName 新的文件名 例如:newFileName
               * @return
               */
              public static boolean downLoadFtpFile(FTPClient ftpClient, String filePath,String downPath, String newFileName)
              {
                  //默認(rèn)失敗
                  boolean flag = false;
          
                  //獲取文件后綴
                  String suffix = getSuffix(filePath);
          
                  //下載的文件對象
                  File dwonFile = new File(downPath + File.separator + newFileName + suffix);
                  try
                  {
                      OutputStream out = new FileOutputStream(dwonFile);
                      flag = ftpClient.retrieveFile(changeEncode(ftpClient,filePath),out);
                      out.flush();
                      out.close();
          
                      if(flag)
                      {
                          log.info("下載文件成功,文件路徑:" + filePath);
                      }else{
                          log.error("下載文件失敗,文件路徑:" + filePath);
                      }
                  }
                  catch (Exception e)
                  {
                      log.error(e.getMessage(),e);
                  }
          
                  return flag;
              }
          
              /**
               * FTP文件上傳工具類
               * @param ftpClient 連接對象
               * @param filePath 本地文件路徑 /xxxx/xx.txt
               * @param ftpPath ftp儲存路徑
               * @param newFileName ftp保存的文件名
               * @return true 下載成功,false 下載失敗
               */
              public static boolean uploadFile(FTPClient ftpClient,String filePath,String ftpPath, String newFileName)
              {
                  boolean flag = false;
          
                  InputStream in = null;
          
                  try {
                      //獲取文件后綴
                      String suffix = getSuffix(filePath);
          
                      //路徑轉(zhuǎn)碼,處理中文
                      ftpPath = changeEncode(ftpClient,ftpPath);
                      newFileName = changeEncode(ftpClient,newFileName + suffix);
          
                      //判斷目標(biāo)文件夾是否存在,不存在就創(chuàng)建
                      if(!ftpClient.changeWorkingDirectory(ftpPath))
                      {
                          ftpClient.makeDirectory(ftpPath);
                          ftpClient.changeWorkingDirectory(ftpPath);
                      }
          
                      //上傳文件
                      File file = new File(filePath);
                      in = new FileInputStream(file);
                      flag = ftpClient.storeFile(newFileName,in);
                      if(flag)
                      {
                          log.info("文件上傳成功:" + filePath);
                      }
                  }
                  catch (Exception e)
                  {
                      log.error(e.getMessage(),e);
                  }
                  finally
                  {
                      try {
                          if(in != null)
                          {
                              in.close();
                          }
                      } catch (IOException e) {
                          log.error(e.getMessage(),e);
                      }
          
                  }
          
                  return flag;
              }
          
              /**
               * FTP上文復(fù)制文件到另外一個路徑
               * @param ftpClient ftp連接對象
               * @param oldFtpPath 源文件儲存路徑 xxx/xxx.txt
               * @param newFtpPath 新路徑 /public/file/
               * @param newFileName 新文件名
               * @return true 下載成功,false 下載失敗
               */
              public static boolean copyFile(FTPClient ftpClient,String oldFtpPath,String newFtpPath, String newFileName)
              {
                  boolean flag = false;
          
                  ByteArrayInputStream in = null;
                  ByteArrayOutputStream out = null;
          
                  try {
                      out = new ByteArrayOutputStream();
          
                      //獲取文件后綴
                      String suffix = getSuffix(oldFtpPath);
          
                      //先讀入內(nèi)存,綁定out輸出流,然后再轉(zhuǎn)換為輸入流
                      String encodeOldPath = changeEncode(ftpClient,oldFtpPath);
                      ftpClient.retrieveFile(encodeOldPath,out);
                      in = new ByteArrayInputStream(out.toByteArray());
          
                      //切換工作目錄,沒有就創(chuàng)建
                      String encodeNewPath = changeEncode(ftpClient,newFtpPath);
                      if(!ftpClient.changeWorkingDirectory(encodeNewPath))
                      {
                          ftpClient.makeDirectory(encodeNewPath);
                          ftpClient.changeWorkingDirectory(encodeNewPath);
                      }
          
                      //復(fù)制文件
                      flag = ftpClient.storeFile(changeEncode(ftpClient,newFileName + suffix),in);
                      out.flush();
                      out.close();
                      in.close();
                      if (flag) {
                          log.info("文件復(fù)制成功,源文件:" + oldFtpPath + " 新路徑:" + newFtpPath + newFileName);
                      } else {
                          throw new BusinessException("文件復(fù)制失敗,源文件:" + oldFtpPath);
                      }
          
                  }
                  catch (Exception e)
                  {
                      log.error(e.getMessage(),e);
                  }
          
                  return flag;
              }
          
              /**
               * 刪除Ftp上的文件
               * @param ftpClient 連接對象
               * @param filePath 服務(wù)器文件路徑 /public/file/xxx.txt
               * @return true 成功,false 失敗
               */
              public static boolean delectFile(FTPClient ftpClient,String filePath)
              {
                  boolean flag = false;
          
                  try {
                      flag = ftpClient.deleteFile(changeEncode(ftpClient,filePath));
                      if(flag)
                      {
                          log.info("刪除文件成功:" + filePath);
                      }else{
                          log.error("刪除文件失敗:" + filePath);
                      }
                  } catch (IOException e) {
                      log.error(e.getMessage(),e);
                  }
          
                  return flag;
              }
          
              /**
               * 文件移動
               * @param ftpClient fpt連接對象
               * @param oldFtpPath 文件原路徑 /public/old/xxx.txt
               * @param newFtpPath 文件新路徑 /public/new/
               * @param newFileName 文件名
               * @return true 成功,false 失敗
               */
              public static boolean moveFile(FTPClient ftpClient,String oldFtpPath,String newFtpPath, String newFileName)
              {
                  boolean flag = false;
          
                  try {
                      //文件后綴
                      String suffix = getSuffix(oldFtpPath);
                      //路徑編碼
                      String encodeOldPath = changeEncode(ftpClient,oldFtpPath);
                      String encodeNewPath = changeEncode(ftpClient,newFtpPath);
                      String encodeNewFileName = changeEncode(ftpClient,newFileName + suffix);
          
                      //切換工作目錄
                      if(!ftpClient.changeWorkingDirectory(encodeNewPath))
                      {
                          ftpClient.makeDirectory(encodeNewPath);
                          ftpClient.changeWorkingDirectory(encodeNewPath);
                      }
          
                      //轉(zhuǎn)存
                      flag = ftpClient.rename(encodeOldPath, encodeNewFileName);
                      if(flag)
                      {
                          log.info("文件轉(zhuǎn)存成功:" + oldFtpPath);
                      }else {
                          log.error("文件轉(zhuǎn)存失敗:" + oldFtpPath);
                      }
          
                  } catch (IOException e) {
                      log.error(e.getMessage(),e);
                  }
                  return flag;
              }
          
              /**
               * 讀取Ftp文本文件,返回行數(shù)據(jù)集合
               * @param ftpClient ftp連接對象
               * @param filePath 文件路徑 /public/file/xxx.txt
               * @param encode 解析文件編碼集
               * @return 行數(shù)據(jù)集合
               */
              public static List<String> redFtpFileWithLine(FTPClient ftpClient, String filePath, String encode)
              {
                  List<String> lineList = new ArrayList<String>();
                  InputStream in = null;
                  BufferedReader reader = null;
          
                  try {
                      //獲取文件流數(shù)據(jù)
                      in = ftpClient.retrieveFileStream(changeEncode(ftpClient,filePath));
                      if(in == null)
                      {
                          throw new BusinessException("獲取文件流失敗:" + filePath);
                      }
                      reader = new BufferedReader(new InputStreamReader(in,encode));
                      String inLine;
                      while ((inLine = reader.readLine()) != null)
                      {
                          lineList.add(inLine);
                      }
          
                      //關(guān)閉流
                      if(reader != null)
                      {
                          reader.close();
                      }
                      in.close();
                      /*
                      retrieveFileStream使用了流,需要釋放一下,不然會返回null
                      方法一:主動調(diào)用一次getReply()把接下來的226消費(fèi)掉
                      方法二:主動調(diào)用一次completePendingCommand(),把流釋放掉
                       */
                      ftpClient.getReply();
          
                  } catch (Exception e) {
                      log.error(e.getMessage(),e);
                  }
          
          
                  return lineList;
              }
          
              /**
               * 獲取文件輸出流
               * @param ftpClient ftp連接對象
               * @param filePath 文件路徑
               * @param out 文件輸出流
               */
              public void readFileWithOutputStream(FTPClient ftpClient, String filePath, OutputStream out)
              {
                  try {
                      if(out == null)
                      {
                          throw new BusinessException("輸出流為null");
                      }
          
                      ftpClient.retrieveFile(filePath,out);
          
                      out.flush();
                      out.close();
          
                  } catch (Exception e) {
                      log.error(e.getMessage(),e);
                  }
              }
          
          }
          
          

          上面只是最簡單的,可以在本地操作ftp上傳下載,在web里面還是有些區(qū)別。這里既然是通過spring進(jìn)行操作,我們不妨在做一些封裝,簡化在項(xiàng)目中的操作。例如我們操作FTP的時候,必要的東西例如,ip,端口,賬號,密碼,這些都是很少進(jìn)行變化的,但是又是在項(xiàng)目中經(jīng)常用的,這里提供一個思路,可以在項(xiàng)目啟動的時候,把這些信息加載到內(nèi)存或者緩存中。

          FtpBean對象,這里展示是省略了get set那些方法的。

          package com.wzh.config.framework.domain;
          
          
          import org.apache.ibatis.type.Alias;
          
          /**
           * @author wzh
           * @create 2018-05-27 20:14
           * @desc ${ftp 對象,用于存儲ftp賬戶信息}
           **/
          @Alias("ftpBean")
          public class FtpBean {
          
              /**
               * fpt別名
               */
              private String ftpName;
          
              /**
               * ftp服務(wù)器ip
               */
              private String ftpHost;
          
              /**
               * ftp服務(wù)器端口
               */
              private String ftpPort;
          
              /**
               * 賬號名
               */
              private String ftpUserName;
          
              /**
               * 密碼
               */
              private String ftpPassword;
          

          Spring 在項(xiàng)目啟動的時候加載一些從數(shù)據(jù)庫中查詢的常量方式很多,可以在xml中配置bean,然后寫init方法,也可以使用注解,或者繼承某些類。這篇博文寫得比較詳細(xì),想詳細(xì)了解的可以看下這篇文章

          https://blog.csdn.net/honghailiang888/article/details/73333821


          因?yàn)檎系膁emo是基于SpringBoot做的,boot中提倡少xml配置文件,所以這里提供一種基于@PostConstruct注解的方式,加載了此注解的方法,會在Spring啟動完成后第一時間執(zhí)行。

          package com.wzh.config.framework.frameworkInit;
          
          import com.wzh.config.framework.domain.FtpBean;
          import com.wzh.config.framework.service.InitFrameWorkConstantService;
          import com.wzh.demo.dao.UserDao;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.stereotype.Component;
          
          import javax.annotation.PostConstruct;
          import javax.annotation.Resource;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;
          
          /**
           * @author wzh
           * @create 2018-05-21 23:58
           * @desc ${系統(tǒng)加載時初始化常量}
           **/
          @Component
          public class InitConstant  {
          
              /**
               * ftp賬號信息對象,靜態(tài),加載到內(nèi)存中
               */
              private static Map<String,Object> ftpInfoMap;
          
              public static Map<String, Object> getFtpInfoMap() {
                  return ftpInfoMap;
              }
          
              @Resource
              @Qualifier(value = "initFrameWorkConstantService")
              private InitFrameWorkConstantService initFrameWorkConstantService;
          
              /**
               * 初始化ftp賬號信息對象
               */
              @PostConstruct
              public void initFtpInfo()
              {
                  ftpInfoMap = new HashMap<String, Object>();
          
                  List<FtpBean> ftpList = initFrameWorkConstantService.initFtpInfo();
                  if(!ftpList.isEmpty())
                  {
                      for (FtpBean bean : ftpList)
                      {
                          //鍵值對方式存放,key為ftp的別名,方便取
                          ftpInfoMap.put(bean.getFtpName(),bean);
                      }
                  }
              }
          }
          

          把之前的FtpUtils再進(jìn)行一下封裝,這里特別說一下,部分方法沒有測試,只是單純的寫了,如果拿來實(shí)際使用,需要再測試一下。這里先把文件在線解析,上傳下載,文件流的方法單獨(dú)說明,其他的方法就不一一演示了,在文末會把代碼貼出來。

          在項(xiàng)目中有這么一個場景,就是用戶上傳實(shí)體文件入庫,有excel的,這種場景一般是在用戶端直接頁面操作,解析后入庫,還有一種是跨平臺實(shí)體文件同步,有的時候有某些大批量的數(shù)據(jù)需要跨平臺同步,如果直接通過接口的方式調(diào)用,文件條數(shù)如果是幾十萬,接口性能并不高,這個時候可以通過ftp文件服務(wù)器的方式同步,大體有兩種,第一種是接口主動通知服務(wù)端,文件已經(jīng)放到ftp服務(wù)器上,還有一種就是定時任務(wù)固定時間掃碼目錄,兩種方式只是觸發(fā)機(jī)制不一樣,當(dāng)時處理邏輯都是相同的。

          文本文件解析方法,這里為了作為通用方法,用了下泛型和反射

              /**
               * 解析txt實(shí)體文件并轉(zhuǎn)換為對應(yīng)的list集合,如果沒有分隔符,用String接收
               * 需注意實(shí)體類與字符串拆分后的順序需相同,排除final 屬性不進(jìn)行設(shè)置值
               * 其實(shí)還有一種方案就是可以用xml等配置文件進(jìn)行配置文件映射,屬性類型,這里為了簡單就直接要求順序相同
               * @param ftpName          ftp別名
               * @param filePath         服務(wù)器文件路徑
               * @param encode           文件編碼集
               * @param regex            文件數(shù)據(jù)分隔符
               * @param obj              解析映射的對象
               * @param simpleDateFormat 解析映射的對象
               * @param <T>              對象泛型
               * @return 返回解析后的集合
               */
              public <T> List<T> readFileWithLine(String ftpName, String filePath, String encode, String regex,
                                                  String simpleDateFormat,T obj) throws Exception{
          
                  //解析后返回的數(shù)據(jù)集合
                  List<T> clazzes = new ArrayList<T>();
          
                  FTPClient ftpClient = linkFtp(ftpName);
          
                  if(null != ftpClient)
                  {
                      List<String> info = FtpUtils.redFtpFileWithLine(ftpClient, filePath, encode);
                      if(null != info && !info.isEmpty())
                      {
                          if(StringUtils.isBlank(regex))
                          {
                              // 無分隔符,判斷為String 集合
                              clazzes.addAll((Collection<? extends T>) info);
          
                          }else {
          
                              for(String str : info)
                              {
                                  // 拆分行數(shù)據(jù)
                                  String [] line = str.split(regex);
          
                                  //因?yàn)镴DK用的1.9 所以沒有直接newInstance,如果是低版本的jdk 可以直接getClass().newInstance
                                  T t = (T) obj.getClass().getDeclaredConstructor().newInstance();
                                  // 獲取文件屬性數(shù)組
                                  Field[] fielders = t.getClass().getDeclaredFields();
          
                                  // 循環(huán)排除final屬性
                                  List<Field> fieldList = new ArrayList<Field>();
                                  for(Field cell : fielders)
                                  {
                                      if(!Modifier.isFinal(cell.getModifiers()))
                                      {
                                          // 非final的屬性才進(jìn)行處理
                                          fieldList.add(cell);
                                      }
                                  }
          
                                  // 數(shù)據(jù)和對象映射要求完全對應(yīng),所以這里取對象下標(biāo)
                                  for(int i = 0; i < fieldList.size(); i++)
                                  {
                                      Field field = fieldList.get(i);
                                      // 設(shè)置權(quán)限
                                      field.setAccessible(true);
          
                                      // 判斷數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換,這里只做了幾種常見類型的判斷,如果有需要可以繼續(xù)添加
                                      String type = field.getType().getName();
                                      try {
          
                                          if("java.lang.Integer".equals(type) || "int".equals(type))
                                          {
                                              field.set(t,NumberUtils.toInt(line[i]));
                                          }
                                          else if("java.lang.Double".equals(type) || "double".equals(type))
                                          {
                                              field.set(t,NumberUtils.toDouble(line[i]));
                                          }
                                          else if("java.lang.Float".equals(type) || "float".equals(type))
                                          {
                                              field.set(t,NumberUtils.toFloat(line[i]));
                                          }
                                          else if("java.lang.Long".equals(type) || "long".equals(type))
                                          {
                                              field.set(t,NumberUtils.toLong(line[i]));
                                          }
                                          else if("java.lang.Short".equals(type) || "short".equals(type))
                                          {
                                              field.set(t,NumberUtils.toShort(line[i]));
                                          }
                                          else if("java.lang.Boolean".equals(type) || "boolean".equals(type))
                                          {
                                              field.set(t, BooleanUtils.toBoolean(line[i]));
                                          }
                                          else if("java.util.Date".equals(type) || "Date".equals(type))
                                          {
                                              SimpleDateFormat sdf=new SimpleDateFormat(simpleDateFormat);
                                              if(StringUtils.isBlank(line[i]))
                                              {
                                                  field.set(t, null);
                                              }else{
                                                  field.set(t, sdf.parse(line[i]));
                                              }
                                          }
                                          else {
                                              field.set(t, line[i]);
                                          }
          
                                      }catch (Exception e){
                                          log.error(e.getMessage(),e);
                                      }
          
                                  }
          
                                  // 添加數(shù)據(jù)
                                  clazzes.add(t);
                              }
                          }
          
                      }
          
                  }
                  return clazzes;
              }

          測試一下,首先弄一個實(shí)體文件

          一個實(shí)體類User,省略get set 方法

          package domin;
          
          import java.util.Date;
          
          /**
           * <一句話功能描述>
           * <功能詳細(xì)描述>
           *
           * @author wzh
           * @version 2018-06-18 16:43
           * @see [相關(guān)類/方法] (可選)
           **/
          public class User {
          
              private String name;
          
              private int age;
          
              private Date birthday;
          
              public User() {
                  super();
              }
          }

          junit 測試

          import base.BaseJunit;
          import com.wzh.config.utils.FtpManagerUtils;
          import domin.User;
          import org.junit.Ignore;
          import org.junit.Test;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Qualifier;
          
          import java.util.Date;
          import java.util.List;
          
          /**
           * <一句話功能描述>
           * <功能詳細(xì)描述>
           * @author wzh
           * @version 2018-06-18 16:16
           * @see [相關(guān)類/方法] (可選)
           **/
          public class ftpTest extends BaseJunit {
              @Autowired
              @Qualifier(value = "ftpManagerUtils")
              private FtpManagerUtils ftpManagerUtils;
          
              @Test
              public void readTextTest()
              {
          
                  User user = new User();
                  try {
                      //對象文本文件
                      List<User> list = ftpManagerUtils.readFileWithLine("FTP_USER_SYSTEM",
                              "/file/userinfo.txt","utf-8","\\|","yyyy-MM-dd",user);
          
                      //字符串集合文件文件
                      List<String> strlist = ftpManagerUtils.readFileWithLine("FTP_USER_SYSTEM",
                              "/file/userinfo.txt","utf-8","","yyyy-MM-dd",new String());
                      System.out.println(list);
                      System.out.println(strlist);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
              }
          }

          通過截圖我們可以看到不管是字符串接收行數(shù)據(jù)還是對象接收,都成功解析了,這個時候就可以根據(jù)自身的業(yè)務(wù)邏輯進(jìn)行處理入庫等操作了。

          在文件上傳服務(wù)器這一塊,處理的思路一般有兩種,如果項(xiàng)目比較小,就直接上傳到工程目錄下,或者把工程目錄掛載出去,把其他文件服務(wù)器的磁盤掛到工程目錄下的文件服務(wù)器。還有一種就是專門的文件服務(wù)器,所有的文件都上傳到文件服務(wù)器,這里做一個用戶端上傳文件后直接把文件上傳到ftp服務(wù)器上的處理方式。

          文件上傳工具類,這里是用戶上傳后直接上傳ftp的場景,如果是先存工程,再傳服務(wù)器,可以用另外一個方法

              /**
               * 上傳文件到ftp服務(wù)器
               * @param ftpName     ftp別名
               * @param file        文件對象
               * @param ftpPath     ftp 服務(wù)器保存路徑
               * @param newFileName 保存的文件名
               * @return 上傳是否成功過
               */
              public boolean upLoadFile(String ftpName, MultipartFile file, String ftpPath, String newFileName){
                  //默認(rèn)失敗
                  boolean flag = false;
          
                  FTPClient ftpClient = linkFtp(ftpName);
                  InputStream in = null;
          
                  if (null != ftpClient) {
                      try {
                          // 獲取文件名
                          String fileName = file.getOriginalFilename();
          
                          // 獲取文件后綴名
                          String suffix = FtpUtils.getSuffix(fileName);
          
                          // 路徑轉(zhuǎn)碼,處理中文
                          ftpPath = FtpUtils.changeEncode(ftpClient,ftpPath);
                          newFileName = FtpUtils.changeEncode(ftpClient,newFileName + suffix);
          
                          // 判斷目標(biāo)文件夾是否存在,不存在就創(chuàng)建
                          if(!ftpClient.changeWorkingDirectory(ftpPath))
                          {
                              ftpClient.makeDirectory(ftpPath);
                              ftpClient.changeWorkingDirectory(ftpPath);
                          }
                          in = file.getInputStream();
                          flag = ftpClient.storeFile(newFileName,in);
                          if(flag)
                          {
                              log.info("文件上傳成功:" + fileName);
                          }
          
                      }catch (Exception e)
                      {
                          log.error("文件上傳失敗:" + e.getMessage(),e);
          
                      }finally
                      {
                          try {
                              if(in != null)
                              {
                                  in.close();
                              }
                          } catch (IOException e) {
                              log.error(e.getMessage(),e);
                          }
          
                          // 關(guān)閉連接
                          FtpUtils.closeFTP(ftpClient);
                      }
          
                  }
          
                  return flag;
              }

          一個頁面,這里用的ftl

          <#import "spring.ftl" as spring />
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                  "http://www.w3.org/TR/html4/loose.dtd">
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <form action="${request.contextPath }/ftp/upload.do" method="POST" enctype="multipart/form-data">
                  文件:<input type="file" name="file"/>
                       <input type="submit"/>
              </form>
          </body>
          </html>

          一個簡單的controller ,里面有把MultipartFile 轉(zhuǎn)換為File 其實(shí)方法也可以直接傳輸入流,這里沒過多糾結(jié),如果需要流的場景可以重載寫一個

          package com.wzh.demo.controller;
          
          import com.wzh.config.utils.FtpManagerUtils;
          import com.wzh.config.utils.FtpUtils;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.beans.factory.annotation.Qualifier;
          import org.springframework.stereotype.Controller;
          import org.springframework.web.bind.annotation.RequestMapping;
          import org.springframework.web.bind.annotation.RequestMethod;
          import org.springframework.web.bind.annotation.RequestParam;
          import org.springframework.web.multipart.MultipartFile;
          
          import javax.annotation.Resource;
          import java.io.File;
          import java.io.IOException;
          import java.util.UUID;
          
          /**
           * <ftp文件上傳控制器>
           * <功能詳細(xì)描述>
           *
           * @author wzh
           * @version 2018-06-18 17:55
           * @see [相關(guān)類/方法] (可選)
           **/
          @Controller
          @RequestMapping("/ftp")
          public class FtpController {
          
              @Autowired
              @Qualifier("ftpManagerUtils")
              private FtpManagerUtils ftpManagerUtils;
          
              @RequestMapping(value = "/upload.do",method = RequestMethod.GET)
              public String toFileUpload()
              {
                  return "/test/fileUpload";
              }
          
              @RequestMapping(value = "/upload.do", method = RequestMethod.POST)
              public String FileUpload(@RequestParam("file") MultipartFile file)
              {
                  String suffix = FtpUtils.getSuffix(file.getOriginalFilename());
          
                  //根據(jù)自身業(yè)務(wù)做處理重命名
                  String newFileName = UUID.randomUUID().toString().replace("-", "");
          
                  //文件上傳
                  ftpManagerUtils.upLoadFile("FTP_USER_SYSTEM",file,"/file/test/",newFileName);
          
          
                  return "/test/fileUpload";
              }
          }
          

          去服務(wù)器查看,有uuid重命名的文件,切能正常打開

          用戶頁面操作,從FTP下載文件,這個沒什么特別好說的,一般這用用在應(yīng)用服務(wù)器數(shù)據(jù)庫中只存儲了用戶的文件名和基本路徑,服務(wù)器放在文件服務(wù)器上,當(dāng)用戶需要下載的時候,從ftp下載文件。

          文件下載工具類,這里就沒有寫特別復(fù)雜,就直接流的方式就可以了

          /**
               * 獲取文件流
               * @param ftpName  ftp別名
               * @param filePath ftp服務(wù)器上文件路徑
               * @param out      輸出流
               */
              public void readFileWithOutputStream(String ftpName, String filePath, OutputStream out)
              {
                  FTPClient ftpClient = linkFtp(ftpName);
          
                  if(null != ftpClient)
                  {
          
                      // 綁定輸出流
                      FtpUtils.readFileWithOutputStream(ftpClient, filePath, out);
          
                      // 關(guān)閉連接
                      FtpUtils.closeFTP(ftpClient);
                  }
              }

          一個簡單的頁面

          <#import "spring.ftl" as spring />
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                  "http://www.w3.org/TR/html4/loose.dtd">
          <html>
          <head>
              <title>Title</title>
          </head>
          <body>
              <form action="${request.contextPath }/ftp/down.do" method="POST" enctype="multipart/form-data">
                  文件:<input type="text" name="fileName"/>
                       <input type="submit"/>
              </form>
          </body>
          </html>

          controller控制器

           @RequestMapping(value = "/down.do",method = RequestMethod.GET)
              public String toFileDown()
              {
          
                  return "test/fileDown";
              }
          
              @RequestMapping(value = "/down.do", method = RequestMethod.POST)
              public String fileDown(HttpServletResponse response, String fileName) {
                  try {
                      // 設(shè)置返回編碼及瀏覽器響應(yīng)類型
                      response.setCharacterEncoding("UTF-8");
                      response.setContentType("multipart/form-data;charset=UTF-8");
          
                      //獲取文件后綴名
                      String suffix = FtpUtils.getSuffix(fileName);
          
                      //根據(jù)自身業(yè)務(wù)做處理重命名
                      String downName = UUID.randomUUID().toString().replace("-", "") + suffix;
          
                      response.setHeader("Content-Disposition", "attachment;fileName=" + downName);
          
          
                      //文件下載,大多數(shù)業(yè)務(wù)邏輯都是頁面?zhèn)鬟f文件名或ID,通過數(shù)據(jù)庫或其他文件查詢出具體文件路徑,這里為了測試,寫死
                      ftpManagerUtils.readFileWithOutputStream("FTP_USER_SYSTEM", "/file/test/" + fileName,
                              response.getOutputStream());
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
          
                  return "test/fileDown";
              }

          測試一下,在代碼中也有說明,正常的下載是文件名傳遞,路徑后臺控制,這里為了測試,寫死了

          點(diǎn)擊查詢下載成功,文件也能正常打開

          這里大概就是spring 整合ftp的常用操作,寫得比較長,常見的功能都實(shí)現(xiàn)了,這里再次說明,很多方式?jīng)]有經(jīng)過嚴(yán)格的測試,如果需要在項(xiàng)目中使用,需要再次測試。


          主站蜘蛛池模板: 一区二区精品久久| 亚洲AV无码一区二区大桥未久| 无码人妻aⅴ一区二区三区有奶水| 精品3d动漫视频一区在线观看| 色偷偷av一区二区三区| 一区二区三区无码高清| 日韩高清一区二区| 精品国产乱码一区二区三区| 久久久久人妻精品一区| 国产精品一区三区| 欧洲精品码一区二区三区免费看| 亚洲欧洲无码一区二区三区| 亚洲AV无码一区二区三区久久精品| 3d动漫精品啪啪一区二区免费| 国产精品免费一区二区三区四区| 视频一区二区三区免费观看 | 无码乱码av天堂一区二区| 在线观看午夜亚洲一区| 国产福利电影一区二区三区,免费久久久久久久精 | 日韩精品无码人妻一区二区三区| 国模视频一区二区| 国产色欲AV一区二区三区| 无码一区二区三区在线| 日本精品啪啪一区二区三区| 精品国产一区二区三区久久狼| 精品国产精品久久一区免费式 | 日韩中文字幕精品免费一区| 3D动漫精品一区二区三区| 中字幕一区二区三区乱码 | 91一区二区三区| 亚洲永久无码3D动漫一区| 无码少妇一区二区性色AV| 国产乱码精品一区二区三区中文| 精品一区二区在线观看| 亚洲视频一区二区在线观看| 日本一区二区三区不卡视频| 精品一区二区三区四区电影| 中文字幕一区视频一线| 久久青草精品一区二区三区| 亚洲一区二区三区免费在线观看| 精产国品一区二区三产区|