2、ftp连接工厂package cn.com.pingtech.common.ftp;import lombok.extern.slf4j.slf4j;import java.io.ioexception;import java.util.concurrent.arrayblockingqueue;/** * 连接工厂 */@slf4jpublic class ftpfactory { //有界队列 private static final arrayblockingqueue<ftpconnection> arrayblockingqueue = new arrayblockingqueue<>(ftpconfig.ftpconnectionsize); protected ftpfactory(){ log.info("init ftpconnectionsize "+ftpconfig.ftpconnectionsize); for(int i = 0; i< ftpconfig.ftpconnectionsize; i++){ //表示如果可能的话,将 e 加到 blockingqueue 里,即如果 blockingqueue 可以容纳,则返回 true,否则返回 false arrayblockingqueue.offer(new ftpconnection()); } } /** * 获取连接 * * @return */ public ftpconnection getftp() { ftpconnection poll = null; try { //取走 blockingqueue 里排在首位的对象,若 blockingqueue 为空,阻断进入等待状态直到 blocking 有新的对象被加入为止 poll = arrayblockingqueue.take(); } catch (interruptedexception e) { e.printstacktrace(); } return poll; } /** * 释放连接 * @param ftp * @return */ public boolean relase(ftpconnection ftp){ return arrayblockingqueue.offer(ftp); } /** * 删除连接 * * @param ftp */ public void remove(ftpconnection ftp) { arrayblockingqueue.remove(ftp); } /** * 关闭连接 */ public void close() { for (ftpconnection connection : arrayblockingqueue) { try { connection.disconnect(); } catch (ioexception e) { e.printstacktrace(); } } }}
3、ftp配置package cn.com.pingtech.common.ftp;/** * ftp 配置类 */public class ftpconfig { public static int defaulttimeoutsecond = 10; public static int connecttimeoutsecond = 10; public static int datatimeoutsecond = 10; public static string host = "127.0.0.1"; public static int port =9999; public static string user = "administrator"; public static string password ="yp886611"; public static int threadpoolsize = 1; public static int ftpconnectionsize = 1; }
4、构建多线程ftp上传任务package cn.com.pingtech.common.ftp;import java.io.file;import java.io.ioexception;import java.util.concurrent.callable;/** * 上传任务 */public class uploadtask implements callable{ private file file; private ftpconnection ftp; private string path; private string filename; private ftpfactory factory; public uploadtask(ftpfactory factory,ftpconnection ftp, file file, string path, string filename){ this.factory = factory; this.ftp = ftp; this.file = file; this.path = path; this.filename = filename; } @override public uploadresult call() throws exception { uploadresult result = null; try { if (ftp == null) { result = new uploadresult(file.getabsolutepath(), false); return result; } //如果连接未开启 重新获取连接 if (!ftp.isconnected()) { factory.remove(ftp); ftp = new ftpconnection(); } //开始上传 result = new uploadresult(file.getname(), ftp.upload(path, filename, file)); } catch (ioexception ex) { result = new uploadresult(file.getname(), false); ex.printstacktrace(); } finally { factory.relase(ftp);//释放连接 } return result; }}
package cn.com.pingtech.common.ftp;/** * 上传结果 */public class uploadresult { private string filename; //文件名称 private boolean result; //是否上传成功 public uploadresult(string filename, boolean result) { this.filename = filename; this.result = result; } public string getfilename() { return filename; } public void setfilename(string filename) { this.filename = filename; } public boolean isresult() { return result; } public void setresult(boolean result) { this.result = result; } public string tostring() { return "[filename=" + filename + " , result=" + result + "]"; }}
注意:实现callable接口的任务线程能返回执行结果
callable接口支持返回执行结果,此时需要调用futuretask.get()方法实现,此方法会阻塞线程直到获取“将来”的结果,当不调用此方法时,主线程不会阻塞
5、ftp上传工具类package cn.com.pingtech.common.ftp;import java.io.file;import java.util.arraylist;import java.util.list;import java.util.concurrent.executorservice;import java.util.concurrent.executors;import java.util.concurrent.future;import java.util.concurrent.timeunit;/** * ftp上传工具包 */public class ftputil { /** * 上传文件 * * @param ftppath * @param listfiles * @return */ public static synchronized list upload(string ftppath, file[] listfiles) { //构建线程池 executorservice newfixedthreadpool = executors.newfixedthreadpool(ftpconfig.threadpoolsize); list<future> results = new arraylist<>(); //创建n个ftp链接 ftpfactory factory = new ftpfactory(); for (file file : listfiles) { ftpconnection ftp = factory.getftp();//获取ftp con uploadtask upload = new uploadtask(factory,ftp, file, ftppath, file.getname()); future submit = newfixedthreadpool.submit(upload); results.add(submit); } list listresults = new arraylist<>(); for (future result : results) { try { //获取线程结果 uploadresult uploadresult = (uploadresult)result.get(30, timeunit.minutes); listresults.add(uploadresult); } catch (exception e) { e.printstacktrace(); } } factory.close(); newfixedthreadpool.shutdown(); return listresults; }}
6、测试上传package cn.com.pingtech.common.ftpclass client { public static void main(string[] args) throws ioexception { string loalpath = "c:\\users\\administrator\\desktop\\test\\0"; string ftppath = "/data/jcz/"; file parentfile = new file(loalpath); list <uploadresult> list = ftputil.upload(ftppath,parentfile.listfiles()); for(uploadresult vo:list){ system.out.println(vo); } }}
注意:ftp协议里面,规定文件名编码为iso-8859-1,所以目录名或文件名需要转码
以上就是java多线程怎么实现ftp批量上传文件的详细内容。
