优化 读取的异步文件过多问题

适用场景: 第三方公司会有很多异步通知文件上传到我的 ftp 服务器上,当解析的时候会依次遍历,时间久了需要遍历的会越来越多,这时就需要优化一下,下面是我的优化方案: 移除文件到指定备份路径下,可以查看文件:testFileRemove.java
(方案:对于已经处理过的文件可以选择移除到备份文件夹下,避免处理前遍历文件过多)

package com.msyd.util;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.msyd.ebei.exception.PlatformException;

public class testFileRemove {
    private static Logger logger = LoggerFactory.getLogger(testFileRemove.class);
    public static final String cz_zip_path = "/app/sftp/zsbank/MSYD";//对账文件保存路径
    public static final String cz_zip_path_bak = "/app/sftp/zsbank/MSYDNotifyFileBak";//异步通知对账文件解析入库后,将该文件备份到此路径

    @Test
    public void testRemove() {
        File fileDir = new File(CommonDef.cz_zip_path);
        if (!fileDir.exists()) {
            logger.error("保存文件夹不存在!");
            return;
        }
        String[] files = fileDir.list();
        batchRemoveOldFiles(files);
    }

    /**移动前十天已经处理过的文件
     * 定时任务每次最多允许移除20个文件至备份文件夹下*/
    public void batchRemoveOldFiles(String[] files) {
        if (null == cz_zip_path_bak) {
            return;
        }
        int succ = 0;
        String dateStr2 = formatToYYYYMMDDSDF(addDays(new Date(), -10)); // 前days天日期
        for (int i = 0; i < files.length; i++) {
            logger.info("成功写入通知备份文件夹内的文件个数为:" + succ + "(每次最多允许移动个数为20个)");
            if (21 == succ) {//每次只允许走20个   21
                break;
            }
            String f = files[i];
            String tradeDateStr = getTradeDate(f);
            if (null == tradeDateStr || "".equals(tradeDateStr)) {
                logger.info("对账文件交易日期为空");
                continue;
            }
            if (Integer.parseInt(tradeDateStr) > Integer.parseInt(dateStr2)) {//如果对账文件的交易日期小于配置日期
                logger.info("对账文件交易日期为" + tradeDateStr + ",大于" + dateStr2 + "," + f + "不需要写入到MSYDNotifyFileBak内");
                continue;
            }
            //确认处理过之后,可以进行移除操作
            int count = 1;// psmm.getCountBankAccountFile(f);
            if (count > 0) {
                logger.info("文件" + f + "已经入库,可以转移到上级目录的同级文件夹MSYDNotifyFileBak内");
                try {
                    doRemove(f);//把文件移动到指定文件夹内,同时删除当前文件夹内的压缩文件
                    ++succ;
                } catch (PlatformException e) {
                    logger.info(e.getMessage(), e);
                }
                continue;
            }
        }
    }

    public void doRemove(String fileName) throws PlatformException {
        boolean b = true;
        File dir = new File(cz_zip_path + File.separator + fileName);
        String toPath = cz_zip_path_bak;
        File fileJia = new File(toPath);
        if (dir.isDirectory()) //检查一个对象是否是文件夹
            doRemove(fileName);
        else {
            // 如果文件夹不存在则创建
            if (!fileJia.exists() && !fileJia.isDirectory()) {
                b = fileJia.mkdir();//mkdirs   如果是多级目录都是未创建,可以调用mkdirs方法
            }
            if (!b) {
                throw new PlatformException("文件夹创建失败");
            }
            b = dir.renameTo(new File(toPath + File.separator + dir.getName()));
            if (!b) {
                throw new PlatformException("移动文件至指定路径失败");
            }
        }
    }

    /**  这是根据具体问题具体分析
     * getTradeDate(获取交易日期) 
     * @param   name
     * @return String    DOM对象    
     * @Exception 异常对象    
     * @since  CodingExample Ver(编码范例查看) 1.1
     * 待处理的SFTP上的文件类似于这种:<BR/>
     * BT_SPF1707180029655_20171030.zip<BR/>
     * AB_DPF1707180029655_20171030.zip<BR/>
     * CHD_20171030_EPF1707180029655.zip<BR/>
     * EF_20171030.zip
     */
    private String getTradeDate(String f) {
        String str = f.substring(0, f.lastIndexOf("."));
        String[] interceptDateStr = str.split("_");
        String tradeDateStr = "";
        if (f.startsWith("BT_")) {//批量扣款对账文件前缀
            tradeDateStr = interceptDateStr[2];
        } else if (f.startsWith("AB_")) {//批量还款对账文件前缀
            tradeDateStr = interceptDateStr[2];
        } else if (f.startsWith("CHD_")) {//开销户对账文件前缀
            tradeDateStr = interceptDateStr[1];
        } else if (f.startsWith("EF_")) {//商户对账文件前缀
            tradeDateStr = interceptDateStr[1];
        } else if (f.startsWith("GH_")) {//平台分账对账文件前缀
            tradeDateStr = interceptDateStr[2];
        } else if (f.startsWith("IJ_")) {//内部户对账文件前缀
            tradeDateStr = interceptDateStr[2];
        }
        return tradeDateStr;
    }

    public static String formatToYYYYMMDDSDF(Date date) {
        SimpleDateFormat sf = new SimpleDateFormat("YYYYMMdd");

        if (date != null) {
            return sf.format(date);
        } else {
            return "null";
        }

    }

    /**
     * 取得指定天数的日期
     * @param dateFormat
     * @return 日期类型
     */
    public static Date addDays(Date date, int diffDays) {
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + diffDays);
            return calendar.getTime();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
 }

【下面这个人写的很好,怕链接流失,所以直接拷贝到下面了,参考资料为:http://www.zuidaima.com/share/1915525327801344.htm

package com.msyd.util;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

import org.junit.Test;

/**java file文件类操作使用方法大全*/
public class fileUtil {
    @Test
    public void test0() {
        //构造函数File(String pathname)
        File f1 = new File("c:\\zuidaima\\1.txt");
        //File(String parent,String child)
        File f2 = new File("c:\\zuidaima", "2.txt");
        //File(File parent,String child)
        File f3 = new File("c:" + File.separator + "abc");//separator 跨平台分隔符
        File f4 = new File(f3, "3.txt");
        System.out.println(f1);//c:\zuidaima\1.txt
    }

    /*创建方法

    1.boolean createNewFile() 不存在返回true 存在返回false
    2.boolean mkdir() 创建目录
    3.boolean mkdirs() 创建多级目录
                删除方法
    1.boolean delete()
    2.boolean deleteOnExit() 文件使用完成后删除*/
    @Test
    public void test1() {
        File f = new File("d:\\zuidaima\\1.txt");
        try {
            System.out.println(f.createNewFile());//当文件存在时返回false
            System.out.println(f.delete());//当文件不存在时返回false
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /*判断方法

    1.boolean canExecute()判断文件是否可执行
    2.boolean canRead()判断文件是否可读
    3.boolean canWrite() 判断文件是否可写
    4.boolean exists() 判断文件是否存在
    5.boolean isDirectory() 
    6.boolean isFile()
    7.boolean isHidden()
    8.boolean isAbsolute()判断是否是绝对路径 文件不存在也能判断

             获取方法

    1.String getName()
    2.String getPath()
    3.String getAbsolutePath()
    4.String getParent()//如果没有父目录返回null
    5.long lastModified()//获取最后一次修改的时间
    6.long length()
    7.boolean renameTo(File f)
    8.File[] liseRoots()//获取机器盘符
    9.String[] list() 
    10.String[] list(FilenameFilter filter)*/
    /**列出磁盘下的文件和文件夹*/
    @Test
    public void test2() {
        File[] files = File.listRoots();
        for (File file : files) {
            System.out.println(file);
            if (file.length() > 0) {
                String[] filenames = file.list();
                for (String filename : filenames) {
                    System.out.println(filename);
                }
            }
        }
    }

    /**文件过滤*/
    @Test
    public void test3() {
        File[] files = File.listRoots();
        for (File file : files) {
            System.out.println(file);
            if (file.length() > 0) {
                String[] filenames = file.list(new FilenameFilter() {
                    //file 过滤目录 name 文件名
                    public boolean accept(File file, String filename) {
                        return filename.endsWith(".mp3");
                    }
                });
                for (String filename : filenames) {
                    System.out.println(filename);
                }
            }
        }
    }

    /*File[]  listFiles()
    File[] listFiles(FilenameFilter filter)*/
    /**利用递归列出全部文件*/
    @Test
    public void test4() {
        File f = new File("e:\\zuidaima");
        showDir(f);
    }

    public void showDir(File dir) {
        System.out.println(dir);
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isDirectory())
                showDir(file);
            else
                System.out.println(file);
        }
    }

    /**移动文件<br/>
                        找出d盘下所有的 .java 文件,拷贝至 c:\jad 目录下,并将所有文件的类型由.java 修改为.jad 。
    */
    @Test
    public void test5() {
        File f1 = new File("d:\\zuidaima\\");
        moveFile(f1);
    }

    public static void moveFile(File dir) {
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isDirectory())
                moveFile(file);
            else {
                if (file.getName().endsWith(".java"))
                    file.renameTo(new File(
                            "c:\\jad\\" + file.getName().substring(0, file.getName().lastIndexOf('.')) + ".jad"));
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_17033579/article/details/82253565