commons.net.ftp


import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;

import java.io.*;
import java.text.ParseException;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

/**

 @Author Canaan
 @Date 2018/3/22 */
@Service
public class ServiceImpl implements Service, ResourceLoaderAware {
    private final static String  FTP_PASSWORD      = "isddsdfc";
    private final static String  FTP_URL           = "ls.csdrt.com.cn";
    private final static String  FTP_USER_NAME     = "idsfsc";
    private final static Integer FTP_PORT          = 21;
    private final static String  FTP_PATH          = "cusdrwewnt/fosfsclock/";    //fpt目录
    private final static String  FTP_ENCODING      = "gbk";   // 归档的文件编码
    private final static String  RESOURCE_FILE_DIR = "qefasd/current/foodclock/";    //下载路径
    private final static String  LOCAL_FILE_PATH   = "F:\\Downloads\\";    //本地路径
    private final        Logger  logger            = LoggerFactory.getLogger(ServiceImpl.class);
    private Resource resource;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        resource = resourceLoader.getResource(RESOURCE_FILE_DIR);
    }


    /**
     从ftp中下载归档<br>
     测试下载时间:
     <li>6798 ms</li><li>6528 ms</li><li>6528 ms</li>
     <li>6523 ms</li><li>6554 ms</li><li>6479 ms</li>
     @return
     */
    @Override
    public FamilyMartArchives downLoadFromFTP(Date date) throws IOException {
    
        FTPClient ftpClient = new FTPClient();

        try {
            //1. 建立连接
            ftpClient.connect(FTP_URL, FTP_PORT);

            //打开FTP服务器
            //登录
            if (!ftpClient.login(FTP_USER_NAME, FTP_PASSWORD)) {
                logger.error("ftp登录失败");
                return null;
            }

            int reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                logger.error("ftp is not positiveCompletion");
                return null;
            }

            //目录切换
            if (!cd(ftpClient, FTP_PATH)) {
                logger.error("ftp目录无效");
                return null;
            }

            //文件预览,没有chk 文件就退出
            String archivesFileName = null;    //找出归档的文件
            boolean flag = false;

            String[] names = ftpClient.listNames();
            if (ArrayUtils.isEmpty(names)) {
                return null;
            }
            for (String name : names) {
                if (StringUtils.containsIgnoreCase(name, "FOODCLOCK") && StringUtils.containsIgnoreCase(name, ".zip")) {
                    archivesFileName = name;
                }
                if (flag || StringUtils.containsIgnoreCase(name, ".chk")) {
                    flag = true;
                }
            }

            if (!flag || StringUtils.isBlank(archivesFileName)) {
              
                logger.error("ftp归档失败,没有【.chk】文件");
                return null;
            }

            //文件下载
            Map<String, List<String>> archives;
            archives = loadFile(ftpClient, archivesFileName);
            if (archives == null || archives.isEmpty()) {
                return null;
            }

            //文件解析,返回归档文件
            return analysis(archives);
        } finally {
            //关闭连接
            closeFTP(ftpClient);
        }

    }

    /**
     归档文件解析
     @param archives

     @return
     */
    private FamilyMartArchives analysis(Map<String, List<String>> archives) {
       //
    }



    /**
     目录切换
     @param ftpClient
     @param path

     @return
     */
    private boolean cd(FTPClient ftpClient, String path) {
        try {
            return ftpClient.changeWorkingDirectory(path);
        } catch (IOException e) {
            logger.error("切换目录失败【{}】", path, e);
            return false;
        }

    }

    /*
    下载文件
     */
    private Map<String, List<String>> loadFile(FTPClient ftpClient, String archivesFileName) throws IOException {
        //TODO 如果本地文件已经存在,是否删除?

        boolean flag = true;
        // 下载文件
        BufferedOutputStream buffOut = null;
        try {
            //锁的双重验证
            if (resource != null && !resource.exists()) {
                synchronized (RESOURCE_FILE_DIR) {
                    if (resource != null && !resource.exists()) {
                        flag = resource.getFile().mkdirs();
                    } else {
                        flag = true;
                    }
                }
            }

            if (resource != null && flag) {
                buffOut = new BufferedOutputStream(new FileOutputStream(resource.getFile()+"\\"+ archivesFileName));
            } else {
                buffOut = new BufferedOutputStream(new FileOutputStream(LOCAL_FILE_PATH + archivesFileName));
            }

            flag = ftpClient.retrieveFile(archivesFileName, buffOut);
        } catch (Exception e) {
            logger.error("ftp文件下载失败!", e);
            return null;
        } finally {
            try {
                if (buffOut != null) {
                    buffOut.flush();
                    buffOut.close();
                }
            } catch (Exception e) {
                //
            }
        }

        //文件解析
            if(flag){
                if (resource != null) {
                    return readFile(resource.getFile().getPath()+"\\"+archivesFileName);
                } else {
                    return readFile(LOCAL_FILE_PATH + archivesFileName);
                }
            }
        return null;
    }

    /**
     读取归档文件的内容
     @return
     @throws IOException
     */
    private Map<String, List<String>> readFile(String filePath) throws IOException {
        Map<String, List<String>> result = new HashMap<>();

        ZipFile zf = new ZipFile(filePath);

        InputStream in = new BufferedInputStream(new FileInputStream(filePath));
        ZipInputStream zin = new ZipInputStream(in);
        //ZipEntry 类用于表示 ZIP 文件条目。
        ZipEntry ze;

        try {
            while ((ze = zin.getNextEntry()) != null) {
                if (ze.isDirectory()) {
                    continue;
                }

                if (ze.getSize() <= 0) {
                    continue;
                }

                List<String> rows = new ArrayList<>();  //记录数
                BufferedReader reader = null;
                try {
                    reader = new BufferedReader(new InputStreamReader(zf.getInputStream(ze), FTP_ENCODING));
                    String contextLine;
                    while ((contextLine = reader.readLine()) != null) {
                        rows.add(contextLine);
                    }

                } finally {
                    try {
                        if (reader != null) {
                            reader.close();
                        }
                    } catch (IOException e) {
                        //
                    }
                }

                result.put(ze.getName(), rows);
            }
        } finally {
            try {
                if (zin != null) {
                    zin.close();
                }
                if (in != null) {
                    in.close();
                }
                if (zf != null) {
                    zf.close();
                }
            } catch (IOException e) {
                //
            }
        }

        return result;
    }

}

 

转载于:https://my.oschina.net/u/2552286/blog/1782827

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值