简介:
要想从本地上传文件到远程服务器,必须要在远程服务器上搭建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服务器的物理目录[此方法是获取到客户端要上传文件的全路径的情况下才能用]
如果不能获取到这个全路径,就使用:
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,调用工具类进行处理】