ftp上传与下载文件
准备工作
服务器已经配置好ftp服务
服务器linux centos 7.4 搭建ftp服务器:https://www.cnblogs.com/mmzs/p/10601683.html
需要用到的jar包:
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
配置文件
- application.yml
# 配置ftp服务器信息
ftp:
# ftp服务器的IP地址
url: 127.0.0.0
# 默认端口是21
port: 21
username: ftpuser
password: ftpuser
# ftp服务器存放文件的路径
remotePath: /data/ftp
# 本地需要上传的文件的路径
localDir: D:/test
# ftp上文件下载到本地存放的路径
downDir: D:/test
- FtpConfig配置信息类
@Getter
@Component
public class FtpConfig {
/**
* ftp服务器地址
*/
@Value("${ftp.url}")
private String url;
/**
* ftp服务器端口
*/
@Value("${ftp.port}")
private int port;
/**
* ftp服务器用户名
*/
@Value("${ftp.username}")
private String username;
/**
* ftp服务器密码
*/
@Value("${ftp.password}")
private String password;
/**
* ftp服务器存放文件的路径
*/
@Value("${ftp.remotePath}")
private String remotePath;
/**
* 本地需要上传的文件的路径
*/
@Value("${ftp.localDir}")
private String localDir;
/**
* 下载文件时,存放在本地的路径
*/
@Value("${ftp.downDir}")
private String downDir;
}
工具类FtpUtil内容
@Slf4j(topic="文件上传/下载===ftp服务器:")
public class FtpUtil {
private static FTPClient mFTPClient = new FTPClient();
private static FtpUtil ftp = new FtpUtil();
public FtpUtil() {
// 在控制台打印操作过程
mFTPClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
}
/**
* 上传文件到ftp服务器
*/
public static boolean ftpUpload(String fileName, String ftpUrl, int ftpPort,
String ftpUsername, String ftpPassword, String ftpLocalDir, String ftpRemotePath) {
boolean result = false;
try {
boolean isConnection = ftp.openConnection(ftpUrl, ftpPort, ftpUsername, ftpPassword);
if (isConnection) {
boolean isSuccess = ftp.upload(ftpRemotePath, ftpLocalDir + "/" + fileName);
if (isSuccess) {
log.info("文件上传成功!");
result = true;
} else {
log.info("文件上传失败!");
result = false;
}
ftp.logout();
} else {
log.info("链接ftp服务器失败,请检查配置信息是否正确!");
result = false;
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 从ftp服务器下载文件到本地
*/
public static boolean ftpDownload(String fileName, String ftpUrl, int ftpPort,
String ftpUsername, String ftpPassword, String ftpRemotePath, String ftpDownDir) {
boolean result = false;
try {
boolean isConnection = ftp.openConnection(ftpUrl, ftpPort, ftpUsername, ftpPassword);
if (isConnection) {
boolean isDownloadOk = ftp.downLoad(fileName, ftpDownDir);
boolean isCreateOk = ftp.createDirectory(ftpRemotePath, ftp.mFTPClient);
if (isDownloadOk && isCreateOk) {
log.info("文件下载成功!");
result = true;
} else {
log.info("文件下载失败!");
result = false;
}
ftp.logout();
} else {
log.info("链接ftp服务器失败,请检查配置信息是否正确!");
result = false;
}
} catch (SocketException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 连接ftp服务器
*
* @param host
* ip地址
* @param port
* 端口号
* @param account
* 账号
* @param pwd
* 密码
* @return 是否连接成功
* @throws SocketException
* @throws IOException
*/
private boolean openConnection(String host, int port, String account, String pwd)
throws SocketException, IOException {
mFTPClient.setControlEncoding("UTF-8");
mFTPClient.connect(host, port);
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
mFTPClient.login(account, pwd);
if (FTPReply.isPositiveCompletion(mFTPClient.getReplyCode())) {
System.err.println(mFTPClient.getSystemType());
FTPClientConfig config = new FTPClientConfig(mFTPClient.getSystemType().split(" ")[0]);
config.setServerLanguageCode("zh");
mFTPClient.configure(config);
return true;
}
}
disConnection();
return false;
}
/**
* 登出并断开连接
*/
public void logout() {
System.err.println("logout");
if (mFTPClient.isConnected()) {
System.err.println("logout");
try {
mFTPClient.logout();
disConnection();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 断开连接
*/
private void disConnection() {
if (mFTPClient.isConnected()) {
try {
mFTPClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 下载文件到本地地址
*
* @param remotePath
* 远程地址
* @param loacal
* 本地地址
* @throws IOException
*/
public boolean downLoad(String remotePath, String localDir) throws IOException {
// 进入被动模式
mFTPClient.enterLocalPassiveMode();
// 以二进制进行传输数据
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
FTPFile[] ftpFiles = mFTPClient.listFiles(remotePath);
if (ftpFiles == null || ftpFiles.length == 0) {
log.info("远程文件不存在");
return false;
} else if (ftpFiles.length > 1) {
log.info("远程文件是文件夹");
return false;
}
long lRemoteSize = ftpFiles[0].getSize();
// 本地文件的地址
File localFileDir = new File(localDir);
if (!localFileDir.exists()) {
localFileDir.mkdirs();
}
File localFile = new File(localFileDir, ftpFiles[0].getName());
long localSize = 0;
FileOutputStream fos = null;
if (localFile.exists()) {
if (localFile.length() == lRemoteSize) {
System.err.println("已经下载完毕");
return true;
} else if (localFile.length() < lRemoteSize) {
// 要下载的文件存在,进行断点续传
localSize = localFile.length();
mFTPClient.setRestartOffset(localSize);
fos = new FileOutputStream(localFile, true);
}
}
if (fos == null) {
fos = new FileOutputStream(localFile);
}
InputStream is = mFTPClient.retrieveFileStream(remotePath);
byte[] buffers = new byte[1024];
long step = lRemoteSize / 10;
long process = localSize / step;
int len = -1;
while ((len = is.read(buffers)) != -1) {
fos.write(buffers, 0, len);
localSize += len;
long newProcess = localSize / step;
if (newProcess > process) {
process = newProcess;
System.err.println("下载进度:" + process);
}
}
is.close();
fos.close();
boolean isDo = mFTPClient.completePendingCommand();
if (isDo) {
System.err.println("下载成功");
} else {
System.err.println("下载失败");
}
return isDo;
}
/**
* 创建远程目录
*
* @param remote
* 远程目录
* @param ftpClient
* ftp客户端
* @return 是否创建成功
* @throws IOException
*/
public boolean createDirectory(String remote, FTPClient ftpClient) throws IOException {
String dirctory = remote.substring(0, remote.lastIndexOf("/") + 1);
if (!dirctory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(dirctory)) {
int start = 0;
int end = 0;
if (dirctory.startsWith("/")) {
start = 1;
}
end = dirctory.indexOf("/", start);
while (true) {
String subDirctory = remote.substring(start, end);
if (!ftpClient.changeWorkingDirectory(subDirctory)) {
if (ftpClient.makeDirectory(subDirctory)) {
ftpClient.changeWorkingDirectory(subDirctory);
} else {
System.err.println("创建目录失败");
return false;
}
}
start = end + 1;
end = dirctory.indexOf("/", start);
if (end <= start) {
break;
}
}
}
return true;
}
/**
* 上传的文件
*
* @param remotePath
* 上传文件的路径地址(文件夹地址)
* @param localPath
* 本地文件的地址
* @throws IOException
* 异常
*/
public boolean upload(String remotePath, String localPath) throws IOException {
// 进入被动模式
mFTPClient.enterLocalPassiveMode();
// 以二进制进行传输数据
mFTPClient.setFileType(FTP.BINARY_FILE_TYPE);
File localFile = new File(localPath);
if (!localFile.exists()) {
System.err.println("本地文件不存在");
return false;
}
String fileName = localFile.getName();
if (remotePath.contains("/")) {
boolean isCreateOk = createDirectory(remotePath, mFTPClient);
if (!isCreateOk) {
System.err.println("文件夹创建失败");
return false;
}
}
// 列出ftp服务器上的文件
FTPFile[] ftpFiles = mFTPClient.listFiles(remotePath);
long remoteSize = 0l;
String remoteFilePath = remotePath + "/" + fileName;
if (ftpFiles.length > 0) {
FTPFile mFtpFile = null;
for (FTPFile ftpFile : ftpFiles) {
if (ftpFile.getName().endsWith(fileName)) {
mFtpFile = ftpFile;
break;
}
}
if (mFtpFile != null) {
remoteSize = mFtpFile.getSize();
if (remoteSize == localFile.length()) {
System.err.println("文件已经上传成功");
return true;
}
if (remoteSize > localFile.length()) {
if (!mFTPClient.deleteFile(remoteFilePath)) {
System.err.println("服务端文件操作失败");
} else {
boolean isUpload = uploadFile(remoteFilePath, localFile, 0);
System.err.println("是否上传成功:" + isUpload);
}
return true;
}
if (!uploadFile(remoteFilePath, localFile, remoteSize)) {
System.err.println("文件上传成功");
return true;
} else {
// 断点续传失败删除文件,重新上传
if (!mFTPClient.deleteFile(remoteFilePath)) {
System.err.println("服务端文件操作失败");
} else {
boolean isUpload = uploadFile(remoteFilePath, localFile, 0);
System.err.println("是否上传成功:" + isUpload);
}
return true;
}
}
}
boolean isUpload = uploadFile(remoteFilePath, localFile, remoteSize);
System.err.println("是否上传成功:" + isUpload);
return isUpload;
}
/**
* 上传文件
*
* @param remoteFile
* 包含文件名的地址
* @param localFile
* 本地文件
* @param remoteSize
* 服务端已经存在的文件大小
* @return 是否上传成功
* @throws IOException
*/
private boolean uploadFile(String remoteFile, File localFile, long remoteSize) throws IOException {
long step = localFile.length() / 10;
long process = 0;
long readByteSize = 0;
RandomAccessFile randomAccessFile = new RandomAccessFile(localFile, "r");
OutputStream os = mFTPClient.appendFileStream(remoteFile);
if (remoteSize > 0) {
// 已经上传一部分的时候就要进行断点续传
process = remoteSize / step;
readByteSize = remoteSize;
randomAccessFile.seek(remoteSize);
mFTPClient.setRestartOffset(remoteSize);
}
byte[] buffers = new byte[1024];
int len = -1;
while ((len = randomAccessFile.read(buffers)) != -1) {
os.write(buffers, 0, len);
readByteSize += len;
long newProcess = readByteSize / step;
if (newProcess > process) {
process = newProcess;
System.err.println("当前上传进度为:" + process);
}
}
os.flush();
randomAccessFile.close();
os.close();
boolean result = mFTPClient.completePendingCommand();
return result;
}
}
访问测试
@RestController
@RequestMapping(value = "/ftp")
@Slf4j(topic="请求ftp服务器")
public class FtpController {
@Autowired
FtpConfig ftpConfig;
@GetMapping("/upload")
public String upload() {
String fileName = "uploadfile.txt";
boolean result = FtpUtil.ftpUpload(fileName, ftpConfig.getUrl(),ftpConfig.getPort(),ftpConfig.getUsername(),
ftpConfig.getPassword(), ftpConfig.getLocalDir(), ftpConfig.getRemotePath());
if (result) {
log.info("=======上传文件"+ fileName +"成功=======");
} else {
log.info("=======上传文件"+ fileName +"失败=======");
}
return result?"上传成功":"上传失败";
}
@GetMapping("/download")
public String download(){
String fileName = "welcome.txt";
boolean result = FtpUtil.ftpDownload(fileName, ftpConfig.getUrl(),ftpConfig.getPort(),ftpConfig.getUsername(),
ftpConfig.getPassword(), ftpConfig.getRemotePath(), ftpConfig.getLocalDir() );
if (result) {
log.info("=======下载文件"+ fileName +"成功=======");
} else {
log.info("=======下载文件"+ fileName +"失败=======");
}
return result?"下载成功":"下载失败";
}
}
测试结果1: 上传成功
测试结果2: 下载成功
代码 github 地址:https://github.com/mmzsblog/springboot-FtpUtil
ftp上传与下载文件的更多相关文章
- ftp上传或下载文件工具类
FtpTransferUtil.java工具类,向ftp上传或下载文件: package utils; import java.io.File; import java.io.FileOutputSt ...
- FTP上传和下载文件的应用
FTP(File Transfer Protocol)协议主要用来在网络上进行文件传输.FTP通讯除了有一个默认的端口21外,还有其他端口,同城两个端口同时进行数据传输.一个是默认的端口(通常为21) ...
- Java 利用FTP上传,下载文件,遍历文件目录
Java实现FTP上传下载文件的工具包有很多,这里我采用Java自带的API,实现FTP上传下载文件.另外JDK1.7以前的版本与其之后版本的API有了较大的改变了. 例如: JDK1.7之前 JDK ...
- 使用脚本在FTP上传、下载文件
由于最近勒索病毒变种又一次爆发,公司内部封锁了TCP 445端口.导致原来通过文件共享的方式上传下载的计划任务无法执行.所以,我开设了FTP服务器来完成这个工作. 关于如何建立FTP服务器,请看这里 ...
- FTP上传、下载文件Demo
前言:最近在做一个app,负责写后台接口,客户那边给了一个FTP的账号密码过来,服务器上面放了一堆的PDF文件,让我们这边自己从上面拿,项目是spriongboot的,做个记录供以后参考. 一.app ...
- 结合阿里云服务器,使用FTP上传和下载文件,出现的问题和解决方案
一.FTP出现的问题 二.在网上找的方案 如果使用FileZilla默认设置连接ftp服务器的话可能会报以下错误: 错误: 无法建立数据连接:ECONNREFUSED - Connection ref ...
- C# FTP上传与下载文件
public class UploadFile { string ftpServerIP; string ftpRemotePath; string ftpUserID; string ftpPass ...
- python FTP上传和下载文件
1. 连接FTP server import ftplib ftp = ftplib.FTP(ftpserver, user, passwd) 等同于 import ftplib ftp = ftpl ...
- linux自动ftp上传与下载文件的简单脚本
#!/bin/sh cd /data/backup/55mysql DATE=`date +'%Y%m%d'`file="55_mysql_"$DATE"03*.rar& ...
随机推荐
- 使用Freemarker 实现JSP页面的静态化
使用Freemarker 静态化网页 一.原理 Freemarker 生成静态页面,首先需要使用自己定义的模板页面,这个模板页面可以是最最普通的html,也可以是嵌套freemarker中的 取值表达 ...
- (3)STM32使用HAL库操作外部中断——实战操作
有了上一篇的基础入门知识,使用Cube创建一个简单的外部中断就容易多了. 一.Cube配置 需求:使用PD10作为外部中断(下降沿触发)控制LED(PD12-PD14) 1.选型 STM32-F4-D ...
- python的 a,b=b,a+b 和 a=b b=a+b 的区别(经典)
刚刚我在学习python的时候,发现下面的这个赋值要把给绕晕了(思考了很久),所以我整理之后写下博文, 希望对未来的学弟学妹有帮助! 永远爱你们的! ----新宝宝 n,a,b=0,0,1 while ...
- 不使用SpringBoot如何将原生Feign集成到Spring中来简化http调用
在微服务架构中,如果使用得是SpringCloud,那么只需要集成SpringFeign就可以了,SpringFeign可以很友好的帮我们进行服务请求,对象解析等工作. 然而SpingCloud是依赖 ...
- 基于百度AI开放平台的人脸识别及语音合成
基于百度AI的人脸识别及语音合成课题 课题需求 (1)人脸识别 在Web界面上传人的照片,后台使用Java技术接收图片,然后对图片进行解码,调用云平台接口识别人脸特征,接收平台返回的人员年龄.性别.颜 ...
- Angular(01)-- 架构概览
声明 本系列文章内容梳理自以下来源: Angular 官方中文版教程 官方的教程,其实已经很详细且易懂,这里再次梳理的目的在于复习和巩固相关知识点,刚开始接触学习 Angular 的还是建议以官网为主 ...
- SAP MM 标准采购组织的分配对于寄售采购订单收货的影响
SAP MM 标准采购组织的分配对于寄售采购订单收货的影响 PO 4100004022 是一个寄售的采购订单, 采购组织是CSAS, 工厂代码SZSP.采购信息记录也是有的, MIGO试图对该采购订单 ...
- ArcGIS API for JavaScript 4.x 本地部署之Apache(含Apache官方下载方法)
IIS.Nginx都说了,老牌的Apache和Tomcat也得说一说(如果喜欢用XAMPP另算) 本篇先说Apache. 安装Apache 这个...说实话,比Nginx难找,Apache最近的版本都 ...
- JavaScript函数定义 ,参数调用
一.JavaScript函数函数: 函数就是一种封装,由事件驱动的或者当它被调用时执行的可重复使用的代码块.定义函数:function 函数名(){函数体;}数不会自动执行,需要被调用才可以执行函数名 ...
- 一、Activity的生命周期和启动模式
1.Activity的生命周期 1.1.典型情况下的生命周期 在有用户参与的情况下,Activity所经过的生命周期的改变. Activity会经历如下生命周期: onCreate-onRestart ...