java连接ftp_Java实现连接FTP服务并传递文件

本文介绍了如何使用Java的FTPClient库连接FTP服务器并上传文件。通过FtpClientUtil类的Builder模式配置连接参数,包括主机地址、端口、用户名、密码等,并提供了上传单个文件、整个目录以及从断点续传的功能。
摘要由CSDN通过智能技术生成

public classFtpClientUtil {privateString host;private intport;privateString username;privateString password;private int bufferSize = 10 * 1024 * 1024;private int soTimeout = 15000;privateFTPClient ftp;publicFTPClient getFtp() {returnftp;

}public voidsetFtp(FTPClient ftp) {this.ftp =ftp;

}privateUploadStatus uploadStatus;publicUploadStatus getUploadStatus() {returnuploadStatus;

}public voidsetUploadStatus(UploadStatus uploadStatus) {this.uploadStatus =uploadStatus;

}public static classBuilder {privateString host;private int port = 21;privateString username;privateString password;private int bufferSize = 1024 * 1024;privateFTPClientConfig config;private int defaultTimeout = 15000;private int connectTimeout = 15000;private int dataTimeout = 15000;private int controlKeepAliveTimeout = 300;private int soTimeout = 15000;publicBuilder() {

}publicBuilder host(String host) {this.host =host;return this;

}public Builder port(intport) {this.port =port;return this;

}publicBuilder username(String username) {this.username =username;return this;

}publicBuilder password(String password) {this.password =password;return this;

}public Builder bufferSize(intbufferSize) {this.bufferSize =bufferSize;return this;

}publicBuilder config(FTPClientConfig config) {this.config =config;return this;

}public Builder defaultTimeout(intdefaultTimeout) {this.defaultTimeout =defaultTimeout;return this;

}public Builder connectTimeout(intconnectTimeout) {this.connectTimeout =connectTimeout;return this;

}public Builder dataTimeout(intdataTimeout) {this.dataTimeout =dataTimeout;return this;

}public Builder soTimeout(intsoTimeout) {this.soTimeout =soTimeout;return this;

}public Builder controlKeepAliveTimeout(intcontrolKeepAliveTimeout) {this.controlKeepAliveTimeout =controlKeepAliveTimeout;return this;

}public FtpClientUtil build() throwsIOException {

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);returninstance;

}

}private FtpClientUtil(String host, int port, String username, String password, intbufferSize,

FTPClientConfig config,int defaultTimeout, int dataTimeout, intconnectTimeout,int controlKeepAliveTimeout, int soTimeout) throwsIOException {this.host =host;this.port =port;this.username =username;this.password =password;this.bufferSize =bufferSize;this.soTimeout =soTimeout;this.ftp = newFTPClient();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() throwsSocketException, 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() throwsIOException {boolean suc = this.ftp.login(this.username, this.password);if (!suc) {throw new IllegalStateException("登录ftp服务器失败");

}return this;

}/*** ftp上传文件功能

*

*@paramfile

* 要上传的文件

*@paramrelativePath

* 要上传到ftp服务器的相对路径

*@return*@throwsIOException*/

public FtpClientUtil upload(File file, String relativePath) throwsIOException {

FileInputStream fInputStream= newFileInputStream(file);return this.upload(fInputStream, file.getName(), relativePath, file.length());

}public FtpClientUtil upload(InputStream inputStream, String name, String relativePath, longlocalSize)throwsIOException {

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) throwsIOException {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];intc;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) throwsIOException {

ftp.setFileType(FTP.BINARY_FILE_TYPE);

changeWorkingDirectory(relativePath);

ftp.enterLocalPassiveMode();return this.ftp.storeFileStream(name);

}public void changeWorkingDirectory(String relativePath) throwsIOException {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上传目录下所有文件的功能

*

*@paramfile

* 要上传的目录

*@paramrelativePath

* 要上传到ftp服务器的相对路径

*@return*@throwsIOException*/

public FtpClientUtil uploadDir(File file, String relativePath) throwsIOException {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上传文件, 调用方不用区分文件是否为目录,由该方法自己区分处理

*

*@paramfile

* 要上传的文件

*@paramrelativePath

* 要上传到ftp服务器的相对路径

*@return*@throwsIOException*/

public FtpClientUtil uploadFree(File file, String relativePath) throwsIOException {if(file.isDirectory()) {this.uploadDir(file, relativePath);

}else{this.upload(file, relativePath);

}return this;

}/*** 本方法是上传的快捷方法,方法中自身包含了ftp 连接、登陆、上传、退出、断开各个步骤

*

*@paramfile

* 要上传的文件

*@paramrelativePath

* 要上传到ftp服务器的相对路径*/

public booleanuploadOneStep(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, longlocalSize) {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 interfaceOutputStreamForUpload {public void write(OutputStream outputStream) throwsIOException;

}public booleanuploadOneStepForStream(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() throwsIOException {this.ftp.logout();return this;

}public voiddisconnect() {this.disconnectFinally();

}private voiddisconnectFinally() {if (this.ftp.isConnected()) {try{this.ftp.disconnect();

}catch(IOException ioe) {

logger.warn("ftp断开服务器链接异常", ioe);

}

}

}

@OverridepublicString toString() {return "FtpClientHelper [host=" + host + ", port=" + port + ", username=" + username + ", password=" +password+ "]";

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值