Win10搭建ftp服务器
- 打开控制面板 -> 程序和功能,点击启用或关闭Windows功能,勾选红色方框内的选项
- 控制面板 -> 管理工具,如下打开IIS管理器
- 先在本地磁盘中创建一个目录用来存放FTP站点的内容,如
E:\FTP站点
- 添加FTP站点(右击网站),站点名称自拟,点击下一步
- 绑定和SSL设置:IP地址为本机ip地址(查看本地ip,在控制台输入命令
ipconfig
),默认端口号为21,SSL选择无SSL(L),如下图所示
- 身份验证和授权信息设置,暂时先授权所有用户,后面可以再修改为指定用户
好了,到此我们的FTP站点就已经配置好了,如下
不过暂时还不能直接访问我们的站点,要先允许该站点能通过防火墙,打开 控制面板 -> Windows Defender 防火墙,点击下方红色方框内的允许应用或功能通过Windows Defender 防火墙
- 为FTP服务器创建指定用户登录,右击此电脑打开管理,在本地用户中添加新用户FTPLogin
- 配置我的FTP站点,第一步设置FTP身份验证,禁用匿名登录;第二步设置FTP授权规则,在添加允许授权规则选择中指定用户,即上一步我们创建的新用户FTPLogin;第三步删除对所有用户的授权;
- 登录FTP服务器,在浏览器中输入网址:
ftp://192.168.56.1
,输入用户名和密码
java代码实现文件上传至FTP服务器
- 新建maven工程 ftp-uploadfile
- 在pom文件中添加依赖commons-net
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>1.4.1</version>
</dependency>
- 写代码,调试代码,代码(面向过程)待优化如下:
package com.hz.ftpuploadfile;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
public class FtpUploadFile {
private final static Log logger = LogFactory.getLog(FtpUploadFile.class);
/**
* 获取ftpClient对象
* @param ftpHost FTP服务器地址
* @param ftpUserName 登录FTP服务器用户名
* @param ftpPassword 登录FTP服务器密码
* @param ftpPort FTP服务器端口
* @return
*/
public static FTPClient getFTPClient(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort) {
FTPClient ftpClient = new FTPClient();
//ftpClient.setControlEncoding("GBK"); // 传输的字符编码(防止乱码),自带的编码是ISO-8859-1,一般不会出现乱码
//超时时间(防止僵死)
//ftpClient.setDataTimeout(1000*60);
//ftpClient.setDefaultTimeout(1000*60);
//工作流的大小
//ftpClient.setBufferSize(1024*4);
//主被动模式(应对FTP服务器的相关安全设置)
ftpClient.enterLocalPassiveMode();
//ftpClient.enterLocalActiveMode();
try {
ftpClient.connect(ftpHost, ftpPort); // 连接FTP服务器
if(ftpClient.isConnected()) {
//使用用户名和密码登录
if(ftpClient.login(ftpUserName, ftpPassword)) {
//判断FTP连接是否可用,源码中是通过判断ReplyCode值(200=< reply <300)
if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
logger.info("FTP连接成功。");
System.out.println("FTP登录成功,ftpHost: ftp:/"+ftpClient.getRemoteAddress());
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
}
}else {
logger.info("未连接到FTP,用户名或密码错误。");
ftpClient.disconnect();
}
}
} catch (SocketException e) {
e.printStackTrace();
logger.info("FTP的IP地址可能错误,请正确配置。");
} catch (IOException e) {
e.printStackTrace();
logger.info("FTP的端口错误,请正确配置。");
}
return ftpClient;
}
/**
* 上传文件
* @param ftpHost FTP服务器地址
* @param ftpUserName 登录FTP服务器用户名
* @param ftpPassword 登录FTP服务器密码
* @param ftpPort FTP服务器端口
* @param ftpPath 上传到FTP服务器的指定目录
* @param filename 上传的文件名
* @param input 文件输入流
* @return 成功返回true,否则返回false
*/
public static boolean uploadFile(String ftpHost, String ftpUserName, String ftpPassword, int ftpPort, String ftpPath, String filename, InputStream input) {
boolean result = false;
FTPClient ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
try {
int reply;
reply = ftpClient.getReplyCode(); //用户名密码错误时,值是530
if (!FTPReply.isPositiveCompletion(reply)) { //判断是否成功登录
//ftpClient.disconnect(); //用户名密码错误时报空指针,是因为在用户名密码不正确时,在上面已执行disconnect操作
return result;
}
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.makeDirectory(ftpPath); //目录不存在则创建目录
ftpClient.changeWorkingDirectory(ftpPath); //切换到要上传的目录
//编码文件名,支持中文文件名
filename = new String(filename.getBytes("GBK"), FTP.DEFAULT_CONTROL_ENCODING);
//上传文件
if (!ftpClient.storeFile(filename, input)) {
System.out.println("文件已存在"); //应该是判断文件是否已存在服务器上
return result;
}
input.close();
ftpClient.logout();
result = true;
} catch (IOException e) {
e.printStackTrace();
} catch (NullPointerException e){
e.printStackTrace();
} finally {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
} catch (IOException e) {}
}
}
return result;
}
public static void main(String[] args) {
String ftpHost = "192.168.56.1";
String ftpUserName = "FTPLogin";
String ftpPassword = "wanwan";
int ftpPort = 21;
//String ftpPath = ""; //目录名, ""表示根目录
String ftpPath = "hz"; //目录名最好是英文,中文目录暂时还未成功上传
String fileName = "test_上传测试.docx"; //要上传的文件名
//上传文件
try{
FileInputStream in=new FileInputStream(new File("D:\\" + fileName)); //要上传的文件所在的目录,这里放的是D盘的根目录下
Boolean result = FtpUploadFile.uploadFile(ftpHost, ftpUserName, ftpPassword, ftpPort, ftpPath, fileName, in);
if(result){
System.out.println(fileName+"文件上传成功");
}else{
System.out.println(fileName+"文件上传失败");
}
} catch (Exception e){
e.printStackTrace();
}
}
}
上传了几个文件,效果图(若浏览器未识别中文,可使用谷歌浏览器)
总结文件上传的思路:首先就是获取FTPClient对象,先连接到服务器,接着用账号和密码登录,最后上传文件。效果等同于直接将文件放到服务器的物理存储目录下,Ctrl+CV
代码使用的是面向过程的思想,接下来会尝试用面向对象的方式来尝试实现文件的上传功能,提升自己的编码能力ing