簡介:
要想從本地上傳檔案到遠端伺服器,必須要在遠端伺服器上搭建FTP伺服器(要現在遠端伺服器上安裝虛拟機,比如Windows Server 2008 R2等等),
然後提供FTP伺服器的IP位址、端口号、使用者名、密碼等資訊,在系統中調用Java程式,将本地檔案通過FTP上傳到遠端伺服器
下面是在本地計算機上搭建FTP伺服器(也是在本機上搭建,這裡沒有伺服器,是以隻是用于模拟遠端伺服器)以及簡單地從本地傳輸檔案到伺服器。
搭建FTP伺服器:
======================= 如果使用的是本機的使用者就可以省略【下面】的步驟 =======================
一、首先我們建立一個使用者賬戶用于登入FTP進行操作。右鍵我的電腦-->管理-->本地使用者群組-->使用者,我們可以看到已經建立好的使用者清單
然後右鍵使用者選項,在下拉菜單中選擇新使用者,開始建立我們的使用者,填寫使用者名稱以及密碼。描述可以不填。然後點選建立。建立完成在右邊的使用者清單中就可以看到我們建立的使用者了。
======================= 如果使用的是本機的使用者就可以省略【上面】的步驟 =======================
二、建立使用者完成後我們開始添加IIS程式服務。打開電腦的【開始】菜單找到【控制台】選項,打開進入,找到【程式】,進入到程式和功能選項欄目,我們可以看到左上方的菜單欄中有一個打開或關閉Windows功能選項,點選進入:
進入到打開或關閉Windows功能界面,我們在好到Internet資訊服務,然後點選打開在FTP伺服器前面打勾,也就是把其子菜單的FTP服務和FTP擴充性打勾,然後點選下方的确定按鈕。【備注:如果這裡失敗了,那麼請看路徑“c:\windows\system32\inetsrv”确認‘inetsrv’檔案夾裡是否有‘iis.msc’檔案。如果沒有,說明IIS相關的windows功能未啟用。】
添加完成 IIS服務之後,開始建立我們的FTP站點,右鍵點選我的電腦選擇管理,然後找到服務和應用程式選項點選打開,接着點選Internet資訊服務管理--此時我們可以看到右邊出現了一個連接配接框。
三、添加站點。
右鍵【網站】-->【添加FTP站點】
下一步,輸入本地IP位址【同理, 如果是遠端伺服器,那麼就輸入遠端伺服器的IP位址,端口号預設為21,可修改】,SSL下選中“允許”,
下一步,按照需要設定好,點【完成】
回到下面的頁面,右鍵重新整理,就可以看到新建立的站點,注意:這個站點是隸屬于ZNZZ040(JG\zoumingqiao)這個使用者下面的
四、測試:
如果站點沒有啟動,則右鍵WebFTP站點-->【管理FTP站點】-->【啟動】,打開DOS視窗,輸入netstat -an,回車,看到21端口正在運作:
說明站點成功運作,可以進行檔案傳輸了,
初步測試:
拷貝本地檔案到上面步驟中設定的FTP的實體路徑E:\FTPLocalDirectory下(這個路徑相當于遠端伺服器的存放檔案的目錄),
然後在浏覽器的位址欄中輸入:ftp://本機(遠端伺服器)位址IP/,回車,就會看到FTP伺服器的目錄下有上傳的檔案,說明FTP伺服器搭建成功!
====================================================================
五、下面是使用JAVA代碼上傳本地檔案到FTP伺服器的實體目錄[此方法是擷取到用戶端要上傳檔案的全路徑的情況下才能用]
如果不能擷取到這個全路徑,就使用:http://www.cnblogs.com/josephcnblog/articles/6930788.html
1、 建立class類:FTPUtils.java
package com.wangzhixuan.commons.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
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;
/**
* 使用FTP進行檔案傳輸
* @author zoumingqiao
*/
public class FTPUtils {
// 這是日志記錄
private static final Logger logger = Logger.getLogger(FTPUtils.class);
//private static String encoding = System.getProperty("file.encoding");
private static String encoding = "UTF-8"; // 這裡要從配置檔案讀進來
// FTPClient對象,操作FTP伺服器和上傳檔案的對象,在下面的方法中會被初始化
private FTPClient client;
// FTP伺服器位址
private String host;
// FTP端口号 預設21
private int port;
// FTP伺服器使用者名
private String username;
// FTP伺服器密碼
private String password;
// FTP遠端目錄
private String remoteDir;
// 本地存儲目錄
private String localDir;
// 檔案路徑通配符 預設列出所有
private String regEx = "*";
// 指定要下載下傳的檔案名
private String downloadFileName;
/**
* 設定連接配接屬性
* @param host FTP伺服器位址
* @param username FTP伺服器使用者名
* @param password FTP伺服器密碼
* @return
*/
public FTPUtils setConfig(String host, String username, String password) {
this.host = host;
this.username = username;
this.password = password;
return this;
}
/**
* 設定連接配接屬性
* @param host FTP伺服器位址
* @param port FTP端口号預設21
* @param username FTP伺服器使用者名
* @param password FTP伺服器密碼
* @return
*/
public FTPUtils setConfig(String host, int port, String username, String password) {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
return this;
}
/**
* 連接配接FTP伺服器
*/
public FTPUtils connectServer() {
// 建立一個FPTClient對象
client = new FTPClient();
// 設定逾時時間
client.setConnectTimeout(30000);
try {
// 1. 連接配接伺服器
if(!client.isConnected()){
// 如果采用預設端口,可以使用client.connect(host)的方式直接連接配接FTP伺服器
client.connect(host, port);
// 登入
client.login(username, password);
// 擷取FTP登入應答碼
int reply = client.getReplyCode();
// 驗證是否登陸成功
if (!FTPReply.isPositiveCompletion(reply)) {
logger.info("未連接配接到FTP,使用者名或密碼錯誤。");
client.disconnect();
throw new RuntimeException("未連接配接到FTP,使用者名或密碼錯誤。");
} else {
logger.info("FTP連接配接成功。IP:"+host +"PORT:" +port);
}
// 2. 設定連接配接屬性
client.setControlEncoding(encoding);
// 設定以二進制方式傳輸
client.setFileType(FTPClient.BINARY_FILE_TYPE);
client.enterLocalPassiveMode();
}
} catch (SocketException e) {
try {
client.disconnect();
} catch (IOException e1) {
}
logger.error("連接配接FTP伺服器失敗" + e.getMessage());
throw new RuntimeException("連接配接FTP伺服器失敗" + e.getMessage());
} catch (IOException e) {
}
return this;
}
/**
* 上傳檔案
* @param files 要上傳的檔案List集合
*/
public void upload(List<File> files){
OutputStream os = null;
try {
// 2. 取本地檔案
if(files == null || files.size()==0) {
logger.warn("檔案數為0,沒有找到可上傳的檔案");
return;
}
logger.info("準備上傳" + files.size() + "個檔案");
// 3. 上傳到FTP伺服器
for(File file : files){
this.connectServer();
// 1、設定遠端FTP目錄
client.changeWorkingDirectory(remoteDir);
logger.info("切換至工作目錄【" + remoteDir + "】");
os = client.storeFileStream(file.getName());
if(os== null) throw new RuntimeException("上傳失敗,請檢查是否有上傳權限");
IOUtils.copy(new FileInputStream(file), os);
IOUtils.closeQuietly(os);
}
logger.info("檔案上傳成功,上傳檔案路徑:" + remoteDir);
} catch (IOException e) {
logger.error("上傳檔案失敗" + e.getMessage());
throw new RuntimeException("上傳檔案失敗" + e.getMessage());
}
}
/**
* 擷取檔案輸出流
* @param fileName 檔案名
* @return
*/
public OutputStream getOutputStream(String fileName){
OutputStream os = null;
this.connectServer();
// 1. 設定遠端FTP目錄
try {
client.changeWorkingDirectory(remoteDir);
logger.info("切換至工作目錄【" + remoteDir + "】");
os = client.storeFileStream(fileName);
if(os== null) throw new RuntimeException("伺服器上建立檔案對象失敗");
return os;
} catch (IOException e) {
logger.error("伺服器上建立檔案對象失敗" + e.getMessage());
throw new RuntimeException("伺服器上建立檔案對象失敗" + e.getMessage());
}
}
/**
* 上傳檔案
* @param files 上傳的檔案的List集合
* @param remoteDir 遠端FTP目錄
*/
public void upload(List<File> files,String remoteDir){
this.remoteDir = remoteDir;
this.upload(files);
}
/**
* 上傳檔案
* @param file 檔案對象
*/
public void upload(File file){
List<File> files = new ArrayList<File>();
files.add(file);
upload(files);
}
/**
* 判斷檔案在FTP上是否存在
* @param fileName 檔案名
* @return
*/
public boolean isFileExist(String fileName) {
boolean result = false;
this.connectServer();
try {
// 1.設定遠端FTP目錄
client.changeWorkingDirectory(remoteDir);
logger.info("切換至工作目錄【" + remoteDir + "】");
// 2.讀取遠端檔案
FTPFile[] ftpFiles = client.listFiles(regEx);
if(ftpFiles.length==0) {
logger.warn("檔案數為0,沒有可下載下傳的檔案!");
return result;
}
// 3.檢查檔案是否存在
for (FTPFile file : ftpFiles) {
if(file.getName().equals(fileName)){
result = true;
break;
}
}
} catch (Exception e) {
logger.error("檢查檔案是否存在失敗" + e.getMessage());
throw new RuntimeException("檢查檔案是否存在失敗" + e.getMessage());
}
return result;
}
/* ============================= 檔案下載下傳 ========================================
// 下載下傳檔案
public List<File> download(){
List<File> files = null;
this.connectServer();
InputStream is = null;
File downloadFile = null;
try {
// 1、設定遠端FTP目錄
client.changeWorkingDirectory(remoteDir);
logger.info("切換至工作目錄【" + remoteDir + "】");
// 2、讀取遠端檔案
FTPFile[] ftpFiles = client.listFiles(regEx);
if(ftpFiles.length==0) {
logger.warn("檔案數為0,沒有可下載下傳的檔案!");
return null;
}
logger.info("準備下載下傳" + ftpFiles.length + "個檔案");
// 3、儲存檔案到本地
for (FTPFile file : ftpFiles) {
//如果有指定下載下傳的檔案
if(StringUtils.isNotBlank(downloadFileName) && !file.getName().equals(downloadFileName)){
continue;
}
if(files == null) files = new ArrayList<File>();
is = client.retrieveFileStream(file.getName());
if(is==null) throw new RuntimeException("下載下傳失敗,檢查檔案是否存在");
downloadFile = new File(localDir + file.getName());
FileOutputStream fos = FileUtils.openOutputStream(downloadFile);
IOUtils.copy(is, fos);
client.completePendingCommand();
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(fos);
//另外一種方式,供參考
//OutputStream is = new FileOutputStream(localFile);
//ftpClient.retrieveFile(ff.getName(), is);
//is.close();
files.add(downloadFile);
}
logger.info("檔案下載下傳成功,下載下傳檔案路徑:" + localDir);
return files;
} catch (IOException e) {
logger.error("下載下傳檔案失敗" + e.getMessage());
throw new RuntimeException("下載下傳檔案失敗" + e.getMessage());
}
}
// 下載下傳檔案
public List<File> download(String remoteDir,String localDir){
this.remoteDir = remoteDir;
this.localDir = localDir;
return this.download();
}
// 下載下傳檔案
// @param remoteDir
// @param regEx 檔案通配符
// @param localDir
// @return
public List<File> download(String remoteDir,String regEx,String localDir){
this.remoteDir = remoteDir;
this.localDir = localDir;
this.regEx = regEx;
return this.download();
}
// 下載下傳檔案
// @param downloadFileName 指定要下載下傳的檔案名稱
// @return
public List<File> download(String downloadFileName){
this.downloadFileName = downloadFileName;
return this.download();
}
* ============================= 檔案下載下傳 ========================================
*/
/**
* 關閉連接配接
*/
public void closeConnect() {
try {
client.disconnect();
logger.info(" 關閉FTP連接配接!!! ");
} catch (IOException e) {
logger.warn(" 關閉FTP連接配接失敗!!! ",e);
}
}
public String getRemoteDir() {
return remoteDir;
}
public void setRemoteDir(String remoteDir) {
this.remoteDir = remoteDir;
}
public String getLocalPath() {
return localDir;
}
public void setLocalPath(String localPath) {
this.localDir = localPath;
}
public String getDownloadFileName() {
return downloadFileName;
}
public void setDownloadFileName(String downloadFileName) {
this.downloadFileName = downloadFileName;
}
@Override
public String toString() {
return "FTPUtil [host=" + host + ", port=" + port + ", username="
+ username + ", password=" + password + "]";
}
}
2、建立一個測試類:FTPUtilsTest.java
package com.zmq.test;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import com.wangzhixuan.commons.utils.FTPUtils;
public class FTPUtilsTest {
/**
* FTPUtils工具類測試
* @param args
*/
public static void main(String[] args) {
FTPUtils ftpUtils = new FTPUtils();
// FTP的使用者名/密碼:如果是本地,那就是本機的建立FTP站點的對應的使用者的使用者名和密碼
ftpUtils.setConfig("FTP伺服器的IP位址", 端口号, "FTP的使用者名", "FTP的密碼");
ftpUtils.connectServer();
List<File> fileList = new ArrayList<File>();
File file1 = new File("F:\\testDirectory\\pic1.jpg");
File file2 = new File("F:\\testDirectory\\pic2.jpg");
File file3 = new File("F:\\testDirectory\\pic3.jpg");
fileList.add(file1);
fileList.add(file2);
fileList.add(file3);
ftpUtils.upload(fileList);
}
}
3、運作測試:
背景列印:因為沒有設定FTP伺服器的存放檔案的目錄,是以這裡列印null,可以看到上傳成功!
2017-06-01 15:59:22,744 INFO [FTPUtils.java:99] : FTP連接配接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,746 INFO [FTPUtils.java:132] : 準備上傳3個檔案
2017-06-01 15:59:22,749 INFO [FTPUtils.java:99] : FTP連接配接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,749 INFO [FTPUtils.java:138] : 切換至工作目錄【null】
2017-06-01 15:59:22,754 INFO [FTPUtils.java:99] : FTP連接配接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,756 INFO [FTPUtils.java:138] : 切換至工作目錄【null】
2017-06-01 15:59:22,759 INFO [FTPUtils.java:99] : FTP連接配接成功。IP:172.20.170.40PORT:21
2017-06-01 15:59:22,761 INFO [FTPUtils.java:138] : 切換至工作目錄【null】
2017-06-01 15:59:22,854 INFO [FTPUtils.java:144] : 檔案上傳成功,上傳檔案路徑:null
檢視FTP的實體路徑,多了一些檔案:
===================================================================
至此,FTP伺服器搭建成功,可以進行其他的操作了【比如在jsp頁面上傳檔案,通路action,調用工具類進行處理】