Java實現跨伺服器上傳檔案功能,java上傳檔案
前幾天做個項目,本身用戶端和管理員端是寫在一起的,共用一台伺服器,客戶上傳的檔案都是存在伺服器的硬碟上的。老龍提出要把用戶端和管理員端分離,這時候使用者上傳的附件的儲存就出現問題了。顯然,把大到幾百M的apk檔案存到資料庫不現實,查了半天,在兩端建立ftp伺服器傳檔案是最快的方法。
具體流程是,使用者登入外網用戶端,上傳檔案到外網的伺服器硬碟上,在此同時,檔案通過外網伺服器訪問內網管理員伺服器的ftp伺服器,傳到內網伺服器的硬碟上。這樣內網伺服器可以對上傳的檔案進行加密簽名工作,之後也通過ftp的方式把檔案回傳到外網伺服器硬碟上,供使用者進行其他動作。
具體實現時用到的工具:Serv-U。Serv-U是一個方便我們在windows上建立ftp伺服器的工具。下載破解後,按照步驟,設定好Ip、連接埠、賬戶密碼、允許ftp訪問的磁碟路徑、操作許可權等,就可以使用了。IP在本機測試的時候就選127.0.0.1,內網測試時就選192.168.0.x。
在java項目中的實現,我自己寫了個工具類,用到了apache的commons-net包,有上傳,下載以及刪除功能。附上代碼:
package app.ftp; 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.OutputStream; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply; /** * FTP伺服器工具類 * */ public class FTPUtils { /** * 上傳檔案至FTP伺服器 * * @param url * 伺服器IP地址 * @param port * 伺服器連接埠 * @param userName * 使用者登入名稱 * @param password * 使用者登入密碼 * @param storePath * 伺服器檔案儲存體路徑 * @param fileName * 伺服器檔案儲存體名稱 * @param is * 檔案輸入資料流 * @return * <b>true</b>:上傳成功 * <br/> * <b>false</b>:上傳失敗 */ public static boolean storeFile (String url, int port, String userName, String password, String storePath, String fileName, InputStream is) { boolean result = false; FTPClient ftp = new FTPClient(); try { // 串連至伺服器,連接埠預設為21時,可直接通過URL串連 ftp.connect(url ,port); // 登入伺服器 ftp.login(userName, password); // 判斷返回碼是否合法 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) { // 不合法時中斷連線 ftp.disconnect(); // 結束程式 return result; } // 判斷ftp目錄是否存在,如果不存在則建立目錄,包括建立多級目錄 String s = "/"+storePath; String[] dirs = s.split("/"); ftp.changeWorkingDirectory("/"); //按順序檢查目錄是否存在,不存在則建立目錄 for(int i=1; dirs!=null&&i<dirs.length; i++) { if(!ftp.changeWorkingDirectory(dirs[i])) { if(ftp.makeDirectory(dirs[i])) { if(!ftp.changeWorkingDirectory(dirs[i])) { return false; } }else { return false; } } } // 設定檔案操作目錄 ftp.changeWorkingDirectory(storePath); // 設定檔案類型,二進位 ftp.setFileType(FTPClient.BINARY_FILE_TYPE); // 設定緩衝區大小 ftp.setBufferSize(3072); // 上傳檔案 result = ftp.storeFile(fileName, is); // 關閉輸入資料流 is.close(); // 登出伺服器 ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { try { // 判斷輸入資料流是否存在 if (null != is) { // 關閉輸入資料流 is.close(); } // 判斷串連是否存在 if (ftp.isConnected()) { // 中斷連線 ftp.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } return result; } /** * 從FTP伺服器下載檔案至本地 * * @param url * 伺服器IP地址 * @param port * 伺服器連接埠 * @param userName * 使用者登入名稱 * @param password * 使用者登入密碼 * @param remotePath * 伺服器檔案儲存體路徑 * @param fileName * 伺服器檔案儲存體名稱 * @param localPath * 本地檔案儲存體路徑 * @return * <b>true</b>:下載成功 * <br/> * <b>false</b>:下載失敗 */ public static boolean retrieveFile (String url, int port, String userName, String password, String remotePath, String fileName, String localPath) { boolean result = false; FTPClient ftp = new FTPClient(); OutputStream os = null; try { // 串連至伺服器,連接埠預設為21時,可直接通過URL串連 ftp.connect(url ,port); // 登入伺服器 ftp.login(userName, password); // 判斷返回碼是否合法 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) { // 不合法時中斷連線 ftp.disconnect(); // 結束程式 return result; } // 設定檔案操作目錄 ftp.changeWorkingDirectory(remotePath); // 設定檔案類型,二進位 ftp.setFileType(FTPClient.BINARY_FILE_TYPE); // 設定緩衝區大小 ftp.setBufferSize(3072); // 設定字元編碼 ftp.setControlEncoding("UTF-8"); // 構造本地檔案對象 File localFile = new File(localPath + "/" + fileName); // 擷取檔案操作目錄下所有檔案名稱 String[] remoteNames = ftp.listNames(); // 迴圈比對檔案名稱,判斷是否含有當前要下載的檔案名稱 for (String remoteName: remoteNames) { if (fileName.equals(remoteName)) { result = true; } } // 檔案名稱比對成功時,進入下載流程 if (result) { // 構造檔案輸出資料流 os = new FileOutputStream(localFile); // 下載檔案 result = ftp.retrieveFile(fileName, os); // 關閉輸出資料流 os.close(); } // 登出伺服器 ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { try { // 判斷輸出資料流是否存在 if (null != os) { // 關閉輸出資料流 os.close(); } // 判斷串連是否存在 if (ftp.isConnected()) { // 中斷連線 ftp.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } return result; } /** * 從FTP伺服器刪除檔案 * * @param url * 伺服器IP地址 * @param port * 伺服器連接埠 * @param userName * 使用者登入名稱 * @param password * 使用者登入密碼 * @param remotePath * 伺服器檔案儲存體路徑 * @param fileName * 伺服器檔案儲存體名稱 * @return * <b>true</b>:刪除成功 * <br/> * <b>false</b>:刪除失敗 */ public static boolean deleteFile (String url, int port, String userName, String password, String remotePath, String fileName) { boolean result = false; FTPClient ftp = new FTPClient(); try { // 串連至伺服器,連接埠預設為21時,可直接通過URL串連 ftp.connect(url ,port); // 登入伺服器 ftp.login(userName, password); // 判斷返回碼是否合法 if (!FTPReply.isPositiveCompletion(ftp.getReplyCode())) { // 不合法時中斷連線 ftp.disconnect(); // 結束程式 return result; } // 設定檔案操作目錄 ftp.changeWorkingDirectory(remotePath); // 設定檔案類型,二進位 ftp.setFileType(FTPClient.BINARY_FILE_TYPE); // 設定緩衝區大小 ftp.setBufferSize(3072); // 設定字元編碼 ftp.setControlEncoding("UTF-8"); // 擷取檔案操作目錄下所有檔案名稱 String[] remoteNames = ftp.listNames(); // 迴圈比對檔案名稱,判斷是否含有當前要下載的檔案名稱 for (String remoteName: remoteNames) { if (fileName.equals(remoteName)) { result = true; } } // 檔案名稱比對成功時,進入刪除流程 if (result) { // 刪除檔案 result = ftp.deleteFile(fileName); } // 登出伺服器 ftp.logout(); } catch (IOException e) { e.printStackTrace(); } finally { try { // 判斷串連是否存在 if (ftp.isConnected()) { // 中斷連線 ftp.disconnect(); } } catch (IOException e) { e.printStackTrace(); } } return result; } public static void main(String[] args) throws FileNotFoundException { // try { // FileInputStream fis = new FileInputStream(new File("D:/Soft Storage/軟體工具箱/HTML_Help_WorkShop_1.3_XiaZaiBa.zip")); // System.out.println(storeFile("192.168.1.2", 21, "admin", "1", "C:/Documents and Settings/Administrator/案頭", RandomUUID.random() + ".zip", fis)); // } catch (FileNotFoundException e) { // e.printStackTrace(); // } // //File file = new File("C:/Users/freed/Desktop/1.txt"); //InputStream is = new FileInputStream(file); //System.out.println(storeFile("127.0.0.1", 21, "feili", "feili", "examples", "2.txt", is)); //System.out.println(retrieveFile("127.0.0.1", 21, "feili", "feili", "examples/jsp", "index.html", "C:/Users/freed/Desktop")); //System.out.println(deleteFile("127.0.0.1", 21, "feili", "feili", "testpath", "1.txt")); } }
需要注意的是上傳檔案的時候要將File檔案先放入fileinputstream中。
以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。