Java多线程上传文件到FTP

1、创建连接工厂

    private static int threadNum = 10;

    private  ArrayBlockingQueue<FtpConnection> arrayBlockingQueue =
            new ArrayBlockingQueue<>(threadNum);

    public FtpFactory(){
        
        for(int i = 0; i< threadNum; i++){
            arrayBlockingQueue.offer(new FtpConnection());
        }
    }

    
    public FtpConnection getFtp(){
        FtpConnection poll = null;
        try {
            poll = arrayBlockingQueue.take();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return poll;
    }

    
    public boolean relase(FtpConnection ftp){
        return arrayBlockingQueue.offer(ftp);
    }

   

    public void remove(FtpConnection ftp){
        arrayBlockingQueue.remove(ftp);
    }

    public void close(){
        for(FtpConnection connection : arrayBlockingQueue){
            try {
                connection.disconnect();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

2、写一个FTP的工具类

public static synchronized List<UploadFileResult> uploadFile(String ftpPath, File[] listFiles,int threadNum) {
        ExecutorService executorService = Executors.newFixedThreadPool(threadNum);//可以自定义threadNum
        List<Future> results = new ArrayList<>();
        FtpFactory factory = new FtpFactory();
        Long length = 0L;
        for (File file : listFiles) {
            FtpConnection ftp = factory.getFtp();
            UploadTask task = new UploadTask(factory,ftp, file, ftpPath, file.getName());
            Future future = executorService.submit(task);
            results.add(future);
            length += file.length();
        }
        System.out.println("length=" + length);
        List<UploadFileResult> listResults = new ArrayList<>();
        for (Future result : results) {
            try {
                UploadFileResult uploadFileResult = (UploadFileResult)result.get(60, TimeUnit.MINUTES);
                listResults.add(uploadFileResult);
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                factory.close();
            }
        }
        factory.close();
        executorService.shutdown();
        return listResults;
    }

3、可自定义返回结果集

private String ftpPathFileName; //ftp文件路径名称
    private boolean result; //是否上传成功
    private File file;

    public UploadFileResult(String ftpPathFileName, boolean result, File file) {
        this.ftpPathFileName = ftpPathFileName;
        this.result = result;
        this.file = file;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public String getFtpPathFileName() {
        return ftpPathFileName;
    }

    public void setFtpPathFileName(String ftpPathFileName) {
        this.ftpPathFileName = ftpPathFileName;
    }

    public boolean isResult() {
        return result;
    }

    public void setResult(boolean result) {
        this.result = result;
    }

    
    }

4、创建上传的task

public class UploadTask implements Callable{

    private File file;
    private FtpConnection ftpConnection;
    private String ftpPath;
    private String fileName;
    private FtpFactory factory;

    public UploadTask(FtpFactory factory, FtpConnection ftpConnection, File file, String ftpPath, String fileName){
        this.factory = factory;
        this.ftpConnection = ftpConnection;
        this.file = file;
        this.ftpPath = ftpPath;
        this.fileName = fileName;
    }

    @Override
    public UploadFileResult call() throws Exception {
        UploadFileResult result = null;
        try{
            if(ftpConnection == null){
                result = new UploadFileResult(file.getAbsolutePath(),false,file);
                return result;
            }
            if(!ftpConnection.isConnected()){
                factory.remove(ftpConnection);
                ftpConnection = new FtpConnection();
            }

            
            FileInputStream inputStream = new FileInputStream(file);
            ftpConnection.uploadFile(ftpPath, fileName, inputStream);
            result = new UploadFileResult(ftpPath + "/" + file.getName(),true,file);
        }catch(IOException e){
            result = new UploadFileResult(ftpPath + "/" + file.getName(),false,file);
            e.printStackTrace();
        }finally{
            factory.relase(ftpConnection);
        }
        
        return result;
    }
}

5、创建FTP连接类

private FTPClient ftpClient = new FTPClient();
    private boolean isConnected = false;

    public FtpConnection(){
        isConnected = false;
        try {
            initConnect("myip", "myport", "myFTPUserName", "myFTPPassWord");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    
    private void initConnect(String host, int port, String userName, String password) throws IOException {
        
        ftpClient.connect(host, port);
        int reply = ftpClient.getReplyCode();
  
        if (!FTPReply.isPositiveCompletion(reply)) {
            disconnect();
        }
        if (!ftpClient.login(userName, password)) {
            isConnected = false;
            disconnect();
        } else {
            isConnected = true;
            
        }
    }

    static String LOCAL_CHARSETUTF_8 = "UTF-8";
    static String SERVER_CHARSET_ISO = "ISO-8859-1";
    static String SERVER_CHARSETGBK = "GBK";

    private static String encodingPath(String path) {
        return StringUtils.toEncodedString(path.replaceAll("//", "/").getBytes(), StandardCharsets.UTF_8);
    }
    
    public void uploadFile(String ftpPath,String ftpFileName, FileInputStream inputStream) throws IOException {
        
        if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("\"OPTS UTF8\", \"ON\""))){
            
            ftpClient.setControlEncoding(LOCAL_CHARSETUTF_8);
        }else {
           
            ftpClient.setControlEncoding(SERVER_CHARSETGBK);
        }
        
        setWorkingDirectory(ftpPath);
        ftpClient.makeDirectory(ftpPath);
        ftpClient.changeWorkingDirectory(ftpPath);
        try {
            ftpClient.enterLocalPassiveMode();
            
            if (!ftpClient.storeFile(ftpFileName, inputStream)) {
                throw new RuntimeException("上传失败");
            }
            inputStream.close();
        }catch (Exception e){
            e.getStackTrace();
        }finally {
            try {
                inputStream.close();
            } catch (IOException ex) {
            }
        }
    }

    
    public void disconnect() throws IOException {
        if (ftpClient.isConnected()) {
            try {
                ftpClient.logout();
                ftpClient.disconnect();
                isConnected = false;
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

   
    private boolean setWorkingDirectory(String dir) {
        if (!isConnected) {
            return false;
        }

        try {
            if(createDirecroty(dir)){
                return ftpClient.changeWorkingDirectory(dir);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

   
    public boolean isConnected(){
        return isConnected;
    }

   
    private boolean createDirecroty(String remote) throws IOException {
        boolean success = true;
        String directory = remote.substring(0, remote.lastIndexOf("/") + 1);

        if (!directory.equalsIgnoreCase("/") && !ftpClient.changeWorkingDirectory(new String(directory))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            while (true) {
                String subDirectory = new String(remote.substring(start, end));
                if (!ftpClient.changeWorkingDirectory(subDirectory)) {
                    if (ftpClient.makeDirectory(subDirectory)) {
                        ftpClient.changeWorkingDirectory(subDirectory);
                    } else {
                       
                        return false;
                    }
                }
                start = end + 1;
                end = directory.indexOf("/", start);

                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

6、Controller

@RequestMapping("/uploadThreads")
    public String uploadThreads(String loalPath,String ftpPath) throws IOException {
        
        File parentFile = new File(loalPath);
        List<UploadFileResult> resultLists = FtpUtils.uploadFile(ftpPath,parentFile.listFiles(),10);//开启10个线程
      if(resultLists != null && resultLists.size() > 0){
            return "success";
        }else{return "error";}
    }

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值