# Java Ftp 文件上传下载
Posted MarlonBrando1998
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了# Java Ftp 文件上传下载相关的知识,希望对你有一定的参考价值。
环境准备
- Win10 搭建 ftp
Ftp 端口
- 21端口:命令端口
- 20端口:FTP传输数据端口,是否会用到20端口与FTP传输模式有关,主动模式使用20端口传输,被动模式下服务器端和客户端协商决定端口。
Ftp 主动模式、被动模式
Ftp支持两种方式的传输:文本(ASCII
)方式和二进制(Binary
)方式,通常文本文件的传输采用ASCII
方式,图像、声音文件等非文本文件采用二进制方式传输。
-
主动模式:客户端向Ftp服务器端发送端口信息,由服务器主动连接该端口。
-
被动模式:FTP服务器开启并发送端口信息给客户端,由客户端连接该端口,服务器被动接受连接。
添加依赖
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
FtpUtils
/**
* @author lidong
*/
public class FtpUtils {
private static final Logger logger = LoggerFactory.getLogger(FtpUtils.class);
/**
* @param ftpUrl ftp 主机地址
* @param ftpUserName 用户名
* @param ftpPassword 密码
* @param port 端口号
* @return
*/
public static FTPClient getFtpClient(String ftpUrl, String ftpUserName, String ftpPassword, int port) {
FTPClient ftpClient = new FTPClient();
try {
// 获取连接
ftpClient.connect(ftpUrl, port);
// 登录
ftpClient.login(ftpUserName, ftpPassword);
int reply;
reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
logger.info("成功登录 ftp 服务器...");
logger.info("成功登录服务器,被动模式主机:[{}:{}]", ftpClient.getPassiveHost(), ftpClient.getPassivePort());
logger.info("成功登录服务器,主动模式主机:[{}:{}]", ftpClient.getRemoteAddress(), ftpClient.getRemotePort());
logger.info("成功登录服务器,本地主机:[{}:{}]", ftpClient.getLocalAddress(), ftpClient.getLocalPort());
logger.info("成功登录服务器,返回代码:[{}], 显示状态[{}]", ftpClient.getReplyCode(), ftpClient.getStatus());
} else {
ftpClient.disconnect();
logger.info("Ftp 登录之后的 ReplyCode{}:", ftpClient.getReplyCode());
}
// 解决创建的文件含有汉字乱码问题
ftpClient.setControlEncoding("UTF-8");
// 设置成以二进制传输
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
} catch (Exception e) {
logger.error(e.getMessage());
}
return ftpClient;
}
/**
* 获得 Ftp 上文件的流
*
* @param ftpClient ftp 连接对象
* @param ftpPathDirectory ftp 上文件目录
* @param fileName 文件名称
* @return
* @throws IOException
*/
public static InputStream getFtpInputStream(FTPClient ftpClient, String ftpPathDirectory, String fileName) throws IOException {
InputStream inputStream = null;
boolean changeWorkingDirectory = ftpClient.changeWorkingDirectory(ftpPathDirectory);
if (!changeWorkingDirectory) {
throw new IllegalArgumentException("当前文件夹不存在!");
}
/**
* 主动模式传送数据时是“服务器”连接到“客户端”的端口;被动模式传送数据是“客户端”连接到“服务器”的端口
* 主动模式需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。
* 被动模式只需要服务器端开放端口给客户端连接就行了。
*/
// 被动模式
ftpClient.enterLocalPassiveMode();
try {
inputStream = ftpClient.retrieveFileStream(new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
} catch (Exception e) {
logger.error("Error Occur{}:", e.getMessage());
}
if (inputStream == null) {
// 主动模式
ftpClient.enterLocalActiveMode();
inputStream = ftpClient.retrieveFileStream(new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
}
Objects.requireNonNull(inputStream);
return inputStream;
}
/**
* 下载 ftp 文件
*
* @param ftpClient
* @param pathDirectory ftp 文件目录
* @param fileName ftp 文件名称
* @param downLoadPath 下载路径
* @return
* @throws IOException
*/
public static String downLoadFtpFile(FTPClient ftpClient, String pathDirectory, String fileName, String downLoadPath) throws IOException {
boolean changeWorkingDirectory = ftpClient.changeWorkingDirectory(pathDirectory);
if (!changeWorkingDirectory) {
throw new IllegalArgumentException("当前文件目录不存在!");
}
// 文件绝对路径
String fileFullPath = downLoadPath + fileName;
File file = new File(fileFullPath);
OutputStream outputStream = new FileOutputStream(file);
for (FTPFile ftpFile : ftpClient.listFiles()) {
String ftpFileName = ftpFile.getName();
logger.info("目录:{} 下有文件:{}", pathDirectory, ftpFileName);
if (ftpFileName.contains(fileName)) {
ftpClient.retrieveFile(ftpFileName, outputStream);
outputStream.close();
}
}
return "下载成功,下载的文件路径为:" + fileFullPath;
}
/**
* 文件上传
*
* @param ftpClient
* @param ftpUploadPath 文件上传 ftp 目录
* @param fileFullPath 本地文件 绝对路径
* @return
* @throws IOException
*/
public static String uploadFtpFile(FTPClient ftpClient, String ftpUploadPath, String fileFullPath) throws IOException {
boolean changeWorkingDirectory = ftpClient.changeWorkingDirectory(ftpUploadPath);
if (!changeWorkingDirectory) {
ftpClient.makeDirectory(ftpUploadPath);
logger.info("在 ftp 下创建文件夹:{}", ftpUploadPath);
}
ftpClient.changeWorkingDirectory(ftpUploadPath);
File file = new File(fileFullPath);
InputStream inputStream = new FileInputStream(file);
ftpClient.storeFile(file.getName(), inputStream);
return "上传成功,上传的文件路径为:" + ftpUploadPath + file.getName();
}
/**
* 列出指定目录下的文件
*
* @param ftpClient
* @param filePathDirectory
* @return
*/
public static FTPFile[] listFtpFiles(FTPClient ftpClient, String filePathDirectory) throws IOException {
boolean changeWorkingDirectory = ftpClient.changeWorkingDirectory(filePathDirectory);
if (!changeWorkingDirectory) {
throw new IllegalArgumentException("当前目录不存在!");
}
return ftpClient.listFiles();
}
private FTPClient getFtpClient() {
String url = "100.100.100.100";
int port = 21;
String username = "admin";
String password = "199917LD";
return getFtpClient(url, username, password, port);
}
@Test
public void testDownLoad() {
try {
String message = downLoadFtpFile(getFtpClient(), "/20210704/", "test_metadata20210701012856.xml", "D:\\\\迅雷云盘\\\\");
logger.info(message);
} catch (IOException e) {
logger.error("Error Occur:{}", e.getMessage());
}
}
@Test
public void testUpLoad() {
try {
String message = uploadFtpFile(getFtpClient(), "/test/", "C:\\\\windows-version.txt");
logger.info(message);
} catch (IOException e) {
logger.error("Error Occur:{}", e.getMessage());
}
}
@Test
public void testListFiles() {
try {
FTPFile[] ftpFiles = listFtpFiles(getFtpClient(), "/test");
for (FTPFile ftpFile : ftpFiles) {
logger.info(ftpFile.getName());
}
} catch (IOException e) {
logger.error(e.getMessage());
}
}
}
以上是关于# Java Ftp 文件上传下载的主要内容,如果未能解决你的问题,请参考以下文章