· FTP服务器搭建
本文使用Win10搭建的FTP服务器,关于Win10下FTP服务器的搭建,搭建可以参考本博的另一篇博文《Win10 搭建FTP服务器 详细设置》。
· Maven 依赖
<dependency>
<groupId>commons-netgroupId>
<artifactId>commons-netartifactId>
<version>3.6version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.4version>
dependency>
· FTP 工具类
package com.arhorchin.securitit.protocol.ftp;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
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;
/**
* @author Securitit.
* @note FTP协议连接HTP服务器工具类.
*/
public class FtpUtil {
/**
* logger.
*/
private Logger logger = Logger.getLogger(FtpUtil.class);
/**
* 文件分隔符.
*/
private String FileSeparator = "/";
/**
* FTP主机地址.
*/
private String host;
/**
* FTP主机端口.
*/
private Integer port;
/**
* FTP登录账号.
*/
private String username;
/**
* FTP登录密码.
*/
private String password;
/**
* FTP客户端.
*/
private FTPClient ftpClient = null;
/**
* 构造基于密码认证的ftp对象.
* @param username FTP登录账号.
* @param password FTP登录密码.
* @param host FTP主机地址.
* @param port FTP主机端口.
*/
public FtpUtil(String username, String password, String host, int port) {
this.username = username;
this.password = password;
this.host = host;
this.port = port;
}
/**
* 连接ftp服务器.
*/
public boolean ftpLogin() {
try {
// 初始化FTP客户端.
ftpClient = new FTPClient();
ftpClient.setControlEncoding("UTF-8");
// 连接FTP服务器.
ftpClient.connect(host, port);
// 登录FTP服务器.
ftpClient.login(username, password);
// 判断是否登录成功.
int replyCode = ftpClient.getReplyCode();
if (!FTPReply.isPositiveCompletion(replyCode)) {
return false;
}
return true;
} catch (Exception ex) {
logger.error(ex);
return false;
}
}
/**
* 关闭连接 server.
*/
public void sftpLogout() {
try {
if (null == ftpClient) {
return;
}
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
ftpClient.logout();
} catch (Exception ex) {
logger.error(ex);
}
}
/**
* 上传文件.
* @param ftpBasepath 基础目录.
* @param ftpFilename 文件名称.
* @param fileBytes 文件内容.
* @return .
*/
public boolean ftpUpload(String ftpBasepath, String ftpFilename, byte[] fileBytes) {
ByteArrayInputStream bais = null;
try {
bais = new ByteArrayInputStream(fileBytes);
ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
// 创建文件目录.
createDirecroty(ftpBasepath);
// 切换工作目录.
ftpClient.changeWorkingDirectory(ftpBasepath);
// 上传文件.
ftpClient.storeFile(ftpFilename, bais);
return true;
} catch (Exception ex) {
logger.error(ex);
return false;
}
}
/**
* 下载文件.
* @param ftpBasepath 基础目录.
* @param ftpFilename 文件名称.
* @return .
*/
public byte[] ftpDownload(String ftpBasepath, String ftpFilename) {
FTPFile[] ftpFiles = null;
ByteArrayOutputStream baos = null;
try {
baos = new ByteArrayOutputStream();
// 切换工作目录.
ftpClient.changeWorkingDirectory(ftpBasepath);
ftpFiles = ftpClient.listFiles();
for (FTPFile file : ftpFiles) {
if (ftpFilename.equalsIgnoreCase(file.getName())) {
ftpClient.retrieveFile(file.getName(), baos);
}
}
return baos.toByteArray();
} catch (Exception ex) {
logger.error(ex);
return null;
}
}
/**
* 删除文件.
* @param ftpBasepath 基础目录.
* @param ftpFilename 文件名称.
* @return .
*/
public boolean ftpDelete(String ftpBasepath, String ftpFilename) {
try {
// 切换工作目录.
ftpClient.changeWorkingDirectory(ftpBasepath);
ftpClient.dele(ftpFilename);
return true;
} catch (Exception ex) {
logger.error(ex);
return false;
}
}
/**
* 切换工作目录.
* @param workDir 工作目录.
* @return 切换结果.
*/
public boolean changeWorkDir(String workDir) throws IOException {
return ftpClient.changeWorkingDirectory(workDir);
}
/**
* 创建服务器目录.
* @param fileDir 文件目录.
* @return 创建结果.
* @throws IOException .
*/
public boolean createDirecroty(String fileDir) throws IOException {
String currentDir = null;
currentDir = fileDir;
// 统一路径格式.
currentDir = currentDir.replaceAll("\\\\", "/");
// 输入路径必须正确.
if (currentDir.equalsIgnoreCase(FileSeparator)) {
return false;
}
// 若工作目录已存在,无需创建.
if (changeWorkDir(new String(currentDir))) {
return true;
}
// 根据参数创建目录.
int prevIndex = 0;
int currentIndex = 0;
currentIndex = currentDir.indexOf("/", 0);
String currentSubDir = null;
while (true) {
if (currentIndex < 0) {
currentIndex = currentDir.length();
}
currentSubDir = currentDir.substring(prevIndex, currentIndex);
if (!existFile(currentSubDir)) {
if (makeDirectory(currentSubDir)) {
changeWorkDir(currentSubDir);
} else {
changeWorkDir(currentSubDir);
}
} else {
changeWorkDir(currentSubDir);
}
if (currentIndex >= currentDir.length()) {
break;
}
prevIndex = currentIndex + 1;
currentIndex = currentDir.indexOf("/", currentIndex + 1);
}
return true;
}
/**
* 判断文件是否存在.
* @param filepath 基础目录.
* @return 是否存在.
* @throws IOException
*/
public boolean existFile(String filepath) throws IOException {
FTPFile[] ftpFileArr = null;
ftpFileArr = ftpClient.listFiles(filepath);
if (ftpFileArr.length > 0) {
return true;
}
return false;
}
/**
* 创建文件目录.
* @param fileDir 文件目录.
* @return 创建结果.
*/
public boolean makeDirectory(String fileDir) throws IOException {
return ftpClient.makeDirectory(fileDir);
}
}
· 测试类如下:
package com.arhorchin.securitit.protocol.ftp;
import java.io.File;
import org.apache.commons.io.FileUtils;
/**
* @author Securitit.
* @note FtpUtil测试类.
*/
public class FtpUtilTester {
public static void main(String[] args) throws Exception {
String ftpIp = "127.0.0.1";
Integer ftpPort = 21;
String ftpUsername = "Securitit";
String ftpPassword = "Wang@881216";
FtpUtil ftp = null;
// 登录SFTP服务器.
ftp = new FtpUtil(ftpUsername, ftpPassword, ftpIp, ftpPort);
ftp.ftpLogin();
byte[] fileBytes = FileUtils.readFileToByteArray(new File("C:/Users/Administrator/Downloads/个人文件/test.pdf"));
// 上传文件.
ftp.ftpUpload("\\Securitit\\", "test.pdf", fileBytes);
}
}
· 总结
· 监控服务器FTP物理路径可以看到文件的变化。
· 测试类输出内容中,可以看到下载的文件长度,说明下载成功了。
· FtpUtil工具类可以拿来直接使用,本人已进行过简单测试。