ftp工具类:上传与下载文件

ftp工具类:上传与下载文件准备工作服务器已经配置好ftp服务linux服务器搭建ftp服务:https://program.blog.csdn.net/article/details/88825921需要用到的jar包:<dependency> <groupId>commons-net</groupId> <artifactId>commons-net</…

大家好,又见面了,我是你们的朋友全栈君。

准备工作

服务器已经配置好ftp服务

linux服务器搭建ftp服务: https://program.blog.csdn.net/article/details/88825921

需要用到的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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/144024.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • Android ListView下拉/上拉刷新:设计原理与实现「建议收藏」

    Android ListView下拉/上拉刷新:设计原理与实现「建议收藏」《AndroidListView下拉/上拉刷新:设计原理与实现》Android上ListView的第三方开源的下拉刷新框架很多,应用场景很多很普遍,几乎成为现在APP的通用设计典范,甚至谷歌官方都索性在AndroidSDK层面支持下拉刷新,我之前写了一篇文章《AndroidSwipeRefreshLayout:谷歌官方SDK包中的下拉刷新》专门介绍过(链接地址:http://bl

  • 图形的光栅化_简述图像的采样和量化过程

    图形的光栅化_简述图像的采样和量化过程在前面的学习中,我们已经可以通过MVP变换,把摄像机观测的物体都压缩成了一个标准立方体,接下来我们要做的是把这个标准立方体绘制到屏幕(Screen)上何为屏幕?一个二维数组,每个元素称之为像素(pixel,pictureelement的缩写),例如我们常说的屏幕分辨率1920*1080,就是说有这么些个像素。屏幕是一个典型的光栅成像设备。光栅(Raster)在德语中就是屏幕的意思,光栅化(Rasterize,名变动)就是把东西画在屏幕上。像素,最小单位,像素内的颜色可以用rgba来定义,一

  • jmeter安装及使用基本教程「建议收藏」

    jmeter安装及使用基本教程「建议收藏」一、安装1.安装jdk,配置环境变量附:JRE(JavaRuntimeEnvironment)Java运行环境,用来运行JAVA程序的。JDK(JavaDevelopmentKit)Java开发工具包,包含JRE。因此只需要下载安装JDK即可中。JDK是SunMicrosystems针对Java开发员的产品,JSP运行环境需要JDK的支持。JDK是整个Java的核心,…

  • Stm32看门狗(开始于2021-07-19)「建议收藏」

    Stm32看门狗(开始于2021-07-19)「建议收藏」Stm32看门狗????1.概述:独立看门狗:喂狗时间必须在0之前,否则计数器下降到0后,产生复位信号;窗口看门狗:喂狗时间必须在CFR寄存器(我们设置的窗口上限),和0x3F(窗口下限)之间(即在CR寄存器的第7位b6*(T6)*减小到零之前),否则(上限之前,或以达下限)均会产生复位信号。喂狗:即重新设置递减计数器CNT的值,也就是手册时序图中的”更新”(CNT).上窗口比较触发:当我们喂狗时,比较器会将当前(未写入时的)CNT的值与CFR低7位的值进行比较,查看是否超前喂狗.2.独立

  • leetcode546_leetcode 5

    leetcode546_leetcode 5DescriptionGivenacollectionofdistinctintegers,returnallpossiblepermutations.ExampleInput:[1,2,3]Output:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]…

  • 开曼群岛的中国大企业(Maluku_Islands)

    http://baike.baidu.com/view/29653.htm开曼群岛百科名片  开曼群岛地理位置开曼群岛(有时也译为凯门群岛)是英国在西加勒比群岛的一块海外属地,由大开曼、小开曼和开曼布拉克3个岛屿组成。开曼群岛是世界第四大离岸金融中心,并是著名的潜水胜地。 查看精彩图册

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号