public class FtpClientUtil {

    private String host;

    private int port;

    private String username;

    private String password;

    private int bufferSize = 10 * 1024 * 1024;

    private int soTimeout = 15000;

    private FTPClient ftp;

    public FTPClient getFtp() {
return ftp;
} public void setFtp(FTPClient ftp) {
this.ftp = ftp;
} private UploadStatus uploadStatus; public UploadStatus getUploadStatus() {
return uploadStatus;
} public void setUploadStatus(UploadStatus uploadStatus) {
this.uploadStatus = uploadStatus;
} public static class Builder {
private String host;
private int port = 21;
private String username;
private String password;
private int bufferSize = 1024 * 1024;
private FTPClientConfig config;
private int defaultTimeout = 15000;
private int connectTimeout = 15000;
private int dataTimeout = 15000;
private int controlKeepAliveTimeout = 300;
private int soTimeout = 15000; public Builder() {
} public Builder host(String host) {
this.host = host;
return this;
} public Builder port(int port) {
this.port = port;
return this;
} public Builder username(String username) {
this.username = username;
return this;
} public Builder password(String password) {
this.password = password;
return this;
} public Builder bufferSize(int bufferSize) {
this.bufferSize = bufferSize;
return this;
} public Builder config(FTPClientConfig config) {
this.config = config;
return this;
} public Builder defaultTimeout(int defaultTimeout) {
this.defaultTimeout = defaultTimeout;
return this;
} public Builder connectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
} public Builder dataTimeout(int dataTimeout) {
this.dataTimeout = dataTimeout;
return this;
} public Builder soTimeout(int soTimeout) {
this.soTimeout = soTimeout;
return this;
} public Builder controlKeepAliveTimeout(int controlKeepAliveTimeout) {
this.controlKeepAliveTimeout = controlKeepAliveTimeout;
return this;
} public FtpClientUtil build() throws IOException {
FtpClientUtil instance = new FtpClientUtil(this.host, this.port, this.username, this.password,
this.bufferSize, this.config, this.defaultTimeout, this.dataTimeout, this.connectTimeout,
this.controlKeepAliveTimeout, this.soTimeout);
return instance;
}
} private FtpClientUtil(String host, int port, String username, String password, int bufferSize,
FTPClientConfig config, int defaultTimeout, int dataTimeout, int connectTimeout,
int controlKeepAliveTimeout, int soTimeout) throws IOException {
this.host = host;
this.port = port;
this.username = username;
this.password = password;
this.bufferSize = bufferSize;
this.soTimeout = soTimeout;
this.ftp = new FTPClient();
if (config != null) {
this.ftp.configure(config);
}
ftp.setControlEncoding("UTF-8");
// ftp.setControlEncoding("GBK");
// ftp.setControlEncoding("gb2312");
ftp.enterLocalPassiveMode();
ftp.setDefaultTimeout(defaultTimeout);
ftp.setConnectTimeout(connectTimeout);
ftp.setDataTimeout(dataTimeout);
// ftp.setSendDataSocketBufferSize(1024 * 256);
if (this.bufferSize > 0) {
ftp.setBufferSize(this.bufferSize);
} // keeping the control connection alive
ftp.setControlKeepAliveTimeout(controlKeepAliveTimeout);// 每大约5分钟发一次noop,防止大文件传输导致的控制连接中断
} public FtpClientUtil connect() throws SocketException, IOException {
if (!this.ftp.isConnected()) {
this.ftp.connect(this.host, this.port);
int reply = this.ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
logger.warn("ftp服务器返回码[{}], 连接失败...", reply);
throw new IllegalStateException("连接ftp服务器失败,返回的状态码是" + reply);
}
}
this.ftp.setSoTimeout(this.soTimeout);
return this;
} public FtpClientUtil login() throws IOException {
boolean suc = this.ftp.login(this.username, this.password);
if (!suc) {
throw new IllegalStateException("登录ftp服务器失败");
}
return this;
} /**
* ftp上传文件功能
*
* @param file
* 要上传的文件
* @param relativePath
* 要上传到ftp服务器的相对路径
* @return
* @throws IOException
*/
public FtpClientUtil upload(File file, String relativePath) throws IOException {
FileInputStream fInputStream = new FileInputStream(file);
return this.upload(fInputStream, file.getName(), relativePath, file.length());
} public FtpClientUtil upload(InputStream inputStream, String name, String relativePath, long localSize)
throws IOException {
ftp.setFileType(FTP.BINARY_FILE_TYPE);
changeWorkingDirectory(relativePath); this.ftp.enterLocalPassiveMode();
FTPFile[] listFiles = this.ftp.listFiles(name);
// long localSize = inputStream.available();// ? 不知道好用否
if (listFiles.length == 1) {
long remoteSize = listFiles[0].getSize(); if (remoteSize == localSize) {
this.setUploadStatus(UploadStatus.File_Exits);
return this;
} else if (remoteSize > localSize) {
this.setUploadStatus(UploadStatus.Remote_Bigger_Local);
return this;
}
this.uploadFile(inputStream, name, remoteSize, localSize);
} else {
this.uploadFile(inputStream, name, 0, localSize);
}
logger.info("{}/{} upload success", relativePath, name);
return this;
} private void uploadFile(InputStream inputStream, String name, long remoteSize, long localSize) throws IOException {
this.ftp.enterLocalPassiveMode();
OutputStream output = null;
long step = localSize / 100;
long process = 0;
long localreadbytes = 0L;
try {
if (remoteSize > 0) {
output = this.ftp.appendFileStream(name);
this.ftp.setRestartOffset(remoteSize);
inputStream.skip(remoteSize);
process = remoteSize / step;
localreadbytes = remoteSize;
} else {
output = this.ftp.storeFileStream(name);
}
byte[] bytes = new byte[1024];
int c;
while ((c = inputStream.read(bytes)) != -1) {
output.write(bytes, 0, c);
localreadbytes += c;
if (localreadbytes / step >= process + 10) {
process = localreadbytes / step;
logger.info("文件【" + name + "】上传ftp进度汇报, process = " + process);
}
}
logger.info("文件" + name + "上传ftp进度汇报, process = " + 100);
output.flush();
inputStream.close();
output.close();
boolean result = this.ftp.completePendingCommand();
if (remoteSize > 0) {
this.setUploadStatus(
result ? UploadStatus.Upload_From_Break_Success : UploadStatus.Upload_From_Break_Failed);
} else {
this.setUploadStatus(
result ? UploadStatus.Upload_New_File_Success : UploadStatus.Upload_New_File_Failed);
}
} catch (Exception e) {
this.setUploadStatus(
remoteSize > 0 ? UploadStatus.Upload_From_Break_Failed : UploadStatus.Upload_New_File_Failed);
} } public OutputStream upload(String name, String relativePath) throws IOException {
ftp.setFileType(FTP.BINARY_FILE_TYPE);
changeWorkingDirectory(relativePath);
ftp.enterLocalPassiveMode();
return this.ftp.storeFileStream(name);
} public void changeWorkingDirectory(String relativePath) throws IOException {
if (relativePath == null) {
throw new NullPointerException("relativePath can't be null");
}
String[] dirs = relativePath.split("/");
for (String dir : dirs) {
if (!this.ftp.changeWorkingDirectory(dir)) {
if (this.ftp.makeDirectory(dir)) {
this.ftp.changeWorkingDirectory(dir);
} else {
logger.warn("{}目录创建失败, 导致不能进入合适的目录进行上传", dir);
}
}
}
} /**
* ftp上传目录下所有文件的功能
*
* @param file
* 要上传的目录
* @param relativePath
* 要上传到ftp服务器的相对路径
* @return
* @throws IOException
*/
public FtpClientUtil uploadDir(File file, String relativePath) throws IOException {
if (!file.isDirectory()) {
throw new IllegalArgumentException("file argument is not a directory!");
}
relativePath = relativePath + "/" + file.getName();
File[] listFiles = file.listFiles();
for (File f : listFiles) {
this.uploadFree(f, relativePath);
}
return this;
} /**
* ftp上传文件, 调用方不用区分文件是否为目录,由该方法自己区分处理
*
* @param file
* 要上传的文件
* @param relativePath
* 要上传到ftp服务器的相对路径
* @return
* @throws IOException
*/
public FtpClientUtil uploadFree(File file, String relativePath) throws IOException {
if (file.isDirectory()) {
this.uploadDir(file, relativePath);
} else {
this.upload(file, relativePath);
}
return this;
} /**
* 本方法是上传的快捷方法,方法中自身包含了ftp 连接、登陆、上传、退出、断开各个步骤
*
* @param file
* 要上传的文件
* @param relativePath
* 要上传到ftp服务器的相对路径
*/
public boolean uploadOneStep(File file, String relativePath) {
try {
this.connect().login().uploadFree(file, relativePath);
return true;
} catch (IOException e) {
String msg = String.format("ftp上传时发生异常, filename = [%s], relativePath = [%s]", file.getName(),
relativePath);
logger.error(msg, e);
return false;
} finally {
this.disconnectFinally();
}
} public boolean uploadOneStepForStream(InputStream inputStram, String name, String relativePath, long localSize) {
try {
this.connect().login().upload(inputStram, name, relativePath, localSize);
return true;
} catch (IOException e) {
String msg = String.format("ftp上传时发生异常, filename = [%s], relativePath = [%s]", name, relativePath);
logger.error(msg, e);
return false;
} finally {
this.disconnectFinally();
}
} public interface OutputStreamForUpload {
public void write(OutputStream outputStream) throws IOException;
} public boolean uploadOneStepForStream(OutputStreamForUpload outputUpload, String name, String relativePath) {
try {
this.connect().login();
OutputStream upload = this.upload(name, relativePath);
outputUpload.write(upload);
return true;
} catch (IOException e) {
String msg = String.format("ftp上传时发生异常, filename = [%s], relativePath = [%s]", name, relativePath);
logger.error(msg, e);
return false;
} finally {
this.disconnectFinally();
}
} public FtpClientUtil logout() throws IOException {
this.ftp.logout();
return this;
} public void disconnect() {
this.disconnectFinally();
} private void disconnectFinally() {
if (this.ftp.isConnected()) {
try {
this.ftp.disconnect();
} catch (IOException ioe) {
logger.warn("ftp断开服务器链接异常", ioe);
}
}
} @Override
public String toString() {
return "FtpClientHelper [host=" + host + ", port=" + port + ", username=" + username + ", password=" + password
+ "]";
} }

看代码吧:

Java实现连接FTP服务并传递文件的更多相关文章

  1. PHP连接FTP服务的简单实现

    PHP连接FTP服务: <?php class Ftp { private $connect; private $getback; /** * ftp连接信息 * @var array */ p ...

  2. ftpget 从Windows FTP服务端获取文件

    /********************************************************************************* * ftpget 从Windows ...

  3. 通过Java WebService接口从服务端下载文件

    一. 前言 本文讲述如何通过webservice接口,从服务端下载文件.报告到客户端.适用于跨系统间的文件交互,传输文件不大的情况(控制在几百M以内).对于这种情况搭建一个FTP环境,增加了系统部署的 ...

  4. java客户端调用ftp上传下载文件

    1:java客户端上传,下载文件. package com.li.utils; import java.io.File; import java.io.FileInputStream; import ...

  5. C# FileStream进行FTP服务上传文件和下载文件

    定义FileStream类的操作类:操作类名: FtpUpDown 上传文件 /// <summary> /// 上传文件 /// </summary> /// <par ...

  6. 【FTP】C# System.Net.FtpClient库连接ftp服务器(上传文件)

    如果自己单枪匹马写一个连接ftp服务器代码那是相当恐怖的(socket通信),有一个评价较高的dll库可以供我们使用. 那就是System.Net.FtpClient,链接地址:https://net ...

  7. java 无法连接ftp服务器(500 OOPS: cannot change directory)

    在使用java连接ftp服务器时可能会出现无法连接的情况,检查代码是没有错误的,这时就应该考虑一下服务器端的情况了: 首先用在本地打开命令窗口,输入:ftp ftp服务器IP,窗口会提示你输入用户名密 ...

  8. C# WebClient进行FTP服务上传文件和下载文件

    定义WebClient使用的操作类: 操作类名称WebUpDown WebClient上传文件至Ftp服务: //// <summary> /// WebClient上传文件至Ftp服务 ...

  9. Java工具-检验ftp服务器的指定文件是否存在

    项目工作中,需要检验ftp服务器中指定文件是否存在,在网上查阅了相关资料,可以通过ftpClient类进行实现. import org.apache.commons.net.ftp.FTP; impo ...

随机推荐

  1. 【总结整理】OpenLayers项目分析,OpenLayers中的图层,GeoServer发布wms服务--实验(转)

    https://blog.csdn.net/u013751758/article/details/44751315 https://blog.csdn.net/u013751758/article/d ...

  2. Codeforces 1109E 线段树

    思路及博客:https://www.cnblogs.com/uid001/p/10507346.html 代码: #include <bits/stdc++.h> #define LL l ...

  3. 十二.filter

    Python内建的filter()函数用于过滤序列. 和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数依次作用于每个元素,然后根据返回值是 ...

  4. vim 的小幅移动

    1.操作符命令和位移 x --->删除一个字符,4x ---->删除4个字符. dw --->可以删除一个单词,d4w ---->删除4个单词. d$  ----> 删除 ...

  5. 61-结点选择(树形dp)

     http://lx.lanqiao.cn/problem.page?gpid=T14 算法训练 结点选择   时间限制:1.0s   内存限制:256.0MB        问题描述 有一棵 n 个 ...

  6. Docker学习笔记_安装和使用mysql

    一.系统环境和准备 1.宿主机OS:Win10 64位 2.虚拟机OS:Ubuntu18.04 3.操作账号:docker 二.安装 1.搜索mysql镜像:docker search mysql 2 ...

  7. 41、OrthoMCL和mcl软件进行基因家族分析

    转载:http://www.realbio.cn/news/124.html https://blog.csdn.net/seallama/article/details/43820763 http: ...

  8. c#缓存介绍

    #缓存介绍(转) 本章导读 缓存主要是为了提高数据的读取速度.因为服务器和应用客户端之间存在着流量的瓶颈,所以读取大容量数据时,使用缓存来直接为客户端服务,可以减少客户端与服务器端的数据交互,从而大大 ...

  9. 使用Boost库(1)

    如何说服你的公司.组织使用Boost库 one of the most highly regarded and expertly designed C++ library projects in th ...

  10. HackThree

    创建自定义ViewGroup ​一,概要:     使用自定义View 和ViewGroup组织应用程序布局是一个好方法,定制组件的同时允许开发者提供自定义行为和功能,以后,开发者 在需要创建复杂布局 ...