Apache Commons工具包介绍及使用方式

Apache Commons工具包介绍及使用方式

BeanUtils

Commons-BeanUtils 提供对 Java 反射和自省API的包装

	@Test
    public void testBeanUtil() throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        Users users = new Users();
        // 将Map数据封装到指定Javabean中,一般用于将表单的所有数据封装到javabean
        HashMap<String, String> map = new HashMap<>();
        map.put("uid", "1111");
        map.put("username", "zhangsan");
        BeanUtils.populate(users, map);
        log.info(users.toString());
        // 设置属性值
        BeanUtils.setProperty(users, "password", "sssssss");
        log.info(users.toString());
        // 获得属性值
        String password = BeanUtils.getProperty(users, "password");
        log.info(password);
        // 对象中的属性值对拷
        Employee employee = new Employee();
        BeanUtils.copyProperties(employee, users);
        log.info(employee.toString());

        Map<String, String> cache = BeanUtils.createCache();
        cache.put("id", "123");
        BeanUtils.setCacheFast(cache, false);
        log.info(cache.toString());
        boolean cacheFast = BeanUtils.getCacheFast(cache);
        log.info(String.valueOf(cacheFast));
        boolean cacheFast2 = BeanUtils.getCacheFast(cache);
        log.info(String.valueOf(cacheFast2));
    }
	/**
	2. 【强制】避免用 Apache Beanutils 进行属性的 copy。
        说明:Apache BeanUtils 性能较差,可以使用其他方案比如 Spring BeanUtils, Cglib BeanCopier,注意均是浅拷贝。
    */

Lang

Commons-Lang3 提供了许多许多通用的工具类集,提供了一些java.lang中类的扩展功能。

Commons Lang3这一组API提供一些基础的、通用的操作和处理,如自动生成toString()的结果、自动实现hashCode()和equals()方法、数组操作、枚举、日期和时间的处理等等。目前这组API的版本是3.14.0。这个工具包可以看成是对java.lang的扩展。提供了诸如StringUtils, StringEscapeUtils, RandomStringUtils, Tokenizer, WordUtils等工具类。

@Slf4j
public class CommonsLangTests {

    @Test
    public void testObjectUtils() {
        List<String> list = new ArrayList<String>();
        if (ObjectUtils.isEmpty(list)) {
            log.info("list是空的。");
        }
        list.add("1、第一条数据");
        if (ObjectUtils.isNotEmpty(list)) {
            log.info("list有数据了。");
        }
        list.add("2、第二条数据");
        log.info("list最大值:{}",ObjectUtils.max(1, 2, 3).toString());
    }

    @Test
    public void testNumberUtils() {
        log.info("null 转int:" + NumberUtils.toInt(null));
        log.info("String 转int:" + NumberUtils.toInt("1"));
        log.info("String 转Double:" + NumberUtils.createDouble("2.3"));
        int[] array = {1, 3, 5, 0};
        log.info("获取最小值:" + NumberUtils.min(array));
        log.info("比较大小:" + NumberUtils.compare(8, 1));
    }

    @Test
    public void testArrayUtils() {
        int[] array = {1, 3, 5, 0};
        log.info("删除指定坐标的元素:" + Arrays.toString(ArrayUtils.remove(array, 1)));
        log.info("删除指定元素:" + Arrays.toString(ArrayUtils.removeElement(array, 0)));
        log.info("添加元素:" + Arrays.toString(ArrayUtils.addFirst(array, 4)));
        log.info("是否包含指定元素:" + ArrayUtils.contains(array, 8));
        log.info("是否包含指定元素:" + ArrayUtils.contains(array, 1));
        log.info("是否包含指定元素:" + ArrayUtils.isEmpty(array));
        int[] array2 = {6, 7, 9, 8};
        log.info("list长度是否相同:" + ArrayUtils.isSameLength(array, array2));
    }

    @Test
    public void testBooleanUtils() {
        log.info("boolean 转int:" + BooleanUtils.toInteger(true));
        log.info("int 转boolean:" + BooleanUtils.toBoolean(0));
        boolean[] array = {true, true, false};
        log.info("是否都是true:" + BooleanUtils.and(array));
        log.info("是否包含true:" + BooleanUtils.or(array));
        log.info("boolean 转为yes/no:" + BooleanUtils.toStringYesNo(true));
    }

    @Test
    public void testRandomStringUtils() {
        log.info("随机字符串-数字:" + RandomStringUtils.randomNumeric(30));
        log.info("随机字符串-字母:" + RandomStringUtils.randomAlphabetic(30));
        log.info("随机字符串-Ascii:" + RandomStringUtils.randomAscii(30));
        log.info("随机字符串-Graph:" + RandomStringUtils.randomGraph(30));
    }

    @Test
    public void testRandomUtils() {
        log.info("随机boolean:" + RandomUtils.nextBoolean());
        log.info("随机数字int:" + RandomUtils.nextInt(100, 1000));
        log.info("随机数字long:" + RandomUtils.nextLong());
    }

    @Test
    public void testSystemUtils() {
        log.info("Home地址:" + SystemUtils.getUserHome());
        log.info("UserName:" + SystemUtils.getUserName());
        log.info("JAVA_HOME:" + SystemUtils.JAVA_HOME);
        log.info("HostName:" + SystemUtils.getHostName());
    }

    @Test
    public void testDateFormatUtils() {
        log.info("当前时间:" + DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:dd"));
        log.info("当前时间:" + DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:dd"));
    }

    @Test
    public void testDateUtils() throws ParseException {
        Date date = new Date();
        log.info("String 转时间:" + DateUtils.parseDate("2021-01-08 14:30:08", "yyyy-MM-dd HH:mm:dd"));
        Date date1 = DateUtils.addDays(date, 1);
        log.info("时间加一天:" + DateFormatUtils.format(date1, "yyyy-MM-dd HH:mm:dd"));
        log.info("时间是否相同:" + DateUtils.isSameDay(date, date1));
        Date date2 = DateUtils.setMonths(date, 5);
        log.info("设置年份:" + DateFormatUtils.format(date2, "yyyy-MM-dd HH:mm:dd"));
        // 将指定的日期中指定的部分四舍五入,四舍五入的常量有
        // Calendar.YEAR
        // Calendar.MONTH、
        // Calendar.HOUR_OF_DAY、
        // Calendar.DAY_OF_MONTH、
        // Calendar.HOUR、
        // Calendar.MINUTE
        Date date3 = DateUtils.round(date2, Calendar.YEAR);
        log.info("日期四舍五入:" + DateFormatUtils.format(date3, "yyyy-MM-dd HH:mm:dd"));
        // 日期截取
        log.info("日期截取:" + DateUtils.truncate(date, Calendar.YEAR));
        log.info("日期截取:" + DateUtils.truncate(date, Calendar.MONTH));
        // 常量说明
        // 周范围,从星期一开始 RANGE_WEEK_MONDAY
        // 周范围,从星期日开始 RANGE_WEEK_SUNDAY
        // 周范围,从星期一开始 RANGE_WEEK_MONDAY
        // 周范围,从关注的那天开始 RANGE_WEEK_RELATIVE
        // 周范围,以关注的天为中心 RANGE_WEEK_CENTER
        // 月范围,从星期日开始 RANGE_MONTH_SUNDAY
        // 月范围,从星期一开始 RANGE_MONTH_MONDAY
        Iterator<Calendar> iterator = DateUtils.iterator(new Date(), DateUtils.RANGE_WEEK_MONDAY);
        while (iterator.hasNext()) {
            Calendar calendar = iterator.next();
            log.info("日期:" + DateFormatUtils.format(calendar.getTimeInMillis(), "yyyy-MM-dd"));
        }
    }

    @Test
    public void testStringUtils() {
        // 重复n次
        log.info(StringUtils.repeat( "=" , 40));

        log.info("判空-空格也当作为空:" + StringUtils.isBlank(" "));
        log.info("判空-空格不当作为空:" + StringUtils.isEmpty(" "));
        log.info("比较两个字符串是否相等,区分大小写:" + StringUtils.equals("abc", "abc"));
        log.info("比较两个字符串是否相等,不区分大小写:" + StringUtils.equalsIgnoreCase("abc", "Abc"));

        log.info("比较字符串 str1 与  str2 的大小,不区分大小写:" + StringUtils.compare("b", "a"));
        log.info("比较字符串 str1 与  str2 的大小,不区分大小写:" + StringUtils.compareIgnoreCase("b", "A"));

        log.info("查找字符串中某个字符或字符串出现的次数:" + StringUtils.countMatches("bsssa", "s"));

        log.info("将数组 array 使用分隔符 separator 连接成字符串:" + StringUtils.join(new String[]{"a", "b", "c"}, "--"));
        log.info("将数组 array 使用分隔符 separator 连接成字符串:" + StringUtils.join(new String[]{}, null));
        log.info("将数组 array 使用分隔符 separator 连接成字符串:" + StringUtils.join(new String[]{"a", "b", "c"}, ""));
        log.info("将数组 array 使用分隔符 separator 连接成字符串:" + StringUtils.join(new String[]{null, "", "a"}, ','));

        log.info("当目标字符串(str)为空,或者为 null,或者是空格,则返回默认字符串:" + StringUtils.defaultIfBlank("bat", "NULL"));
        log.info("当目标字符串(str)为空,或者为 null,则返回默认字符串:" + StringUtils.defaultIfEmpty(" ", "NULL"));

        log.info("判断字符串是否是数字,不忽略空格:" + StringUtils.isNumeric(null));
        log.info("判断字符串是否是数字,不忽略空格:" + StringUtils.isNumeric(""));
        log.info("判断字符串是否是数字,不忽略空格:" + StringUtils.isNumeric("  "));
        log.info("判断字符串是否是数字,不忽略空格:" + StringUtils.isNumeric("123"));
        log.info("判断字符串是否是数字,不忽略空格:" + StringUtils.isNumeric("\u0967\u0968\u0969"));

        log.info("判断字符串是否是数字,忽略空格:" + StringUtils.isNumericSpace(null));
        log.info("判断字符串是否是数字,忽略空格:" + StringUtils.isNumericSpace(""));
        log.info("判断字符串是否是数字,忽略空格:" + StringUtils.isNumericSpace("  "));
        log.info("判断字符串是否是数字,忽略空格:" + StringUtils.isNumericSpace("12 3"));
        log.info("判断字符串是否是数字,忽略空格:" + StringUtils.isNumericSpace("\u0967\u0968\u0969"));

        log.info("判断字符串是否是希腊字母,不忽略空格:" + StringUtils.isAlpha("abc"));
        log.info("判断字符串是否是希腊字母,不忽略空格:" + StringUtils.isAlpha("ab2c"));
        log.info("判断字符串是否是希腊字母,不忽略空格:" + StringUtils.isAlpha("ab-c"));

        log.info("判判断字符串是否全是小写字母:" + StringUtils.isAllLowerCase("abc"));
        log.info("判判断字符串是否全是小写字母:" + StringUtils.isAllLowerCase("abAc"));
        log.info("判判断字符串是否全是小写字母:" + StringUtils.isAllLowerCase("ab-c"));
        log.info("判判断字符串是否全是小写字母:" + StringUtils.isAllUpperCase("ABX"));

        log.info("判断源字符串是否包含字符串区分大小写:" + StringUtils.contains("abc", "a"));
        log.info("判断源字符串是否包含字符串区分大小写:" + StringUtils.contains("abc", ""));
        log.info("判断源字符串是否包含字符串不区分大小写:" + StringUtils.containsAny("abc", "A"));
    }

    @Test
    public void testMath() {
        log.info(StringUtils.center(" demoFraction ", 30, "="));
        Fraction myFraction = Fraction.getFraction(144, 90);
        // Fraction myFraction = Fraction.getFraction("1 54/90");
        log.info("144/90 as fraction: " + myFraction);
        log.info("144/90 to proper: " + myFraction.toProperString());
        log.info("144/90 as double: " + myFraction.doubleValue());
        log.info("144/90 reduced: " + myFraction.reduce());
        log.info("144/90 reduced proper: " + myFraction.reduce().toProperString());

        log.info(StringUtils.center("demoNumberUtils ", 30, "="));
        log.info("Is 0x3Fa number? :" + StringUtils.capitalize(BooleanUtils.toStringYesNo(NumberUtils.isCreatable("0x3F"))) + ".");
    }
    
    @Test
    public void testObjectUtils() {
        log.info("获取随机数:" + RandomUtils.nextInt());
        log.info("获取随机数:" + RandomUtils.nextInt(1, 10));
        log.info("获取随机数:" + RandomUtils.nextBoolean());
        log.info("获取随机数:" + RandomUtils.nextLong());
    }

}

Collections

Commons-Collections 提供一个类包来扩展和增加标准的 Java Collection框架。

@Slf4j
public class CollectionsUtilsTests {

    /**
     * 直译就是双向Map,可以通过key找到value,也可以通过value找到key,
     * 这在我们日常的代码-名称匹配的时候很方便:因为我们除了需要通过代码找到名称之外,往往也需要处理用户输入的名称,然后获取其代码。
     * 需要注意的是BidiMap当中不光key不能重复,value也不可以。
     */
    @Test
    public void testBidiMap() {
        BidiMap bidiMap = new DualHashBidiMap();
        bidiMap.put("BJ", "Beijing");
        bidiMap.put("SH", "Shanghai");
        bidiMap.put("GZ", "Guangzhou");
        bidiMap.put("CD", "Chengdu");
        log.info("根据Key获取Value: BJ = " + bidiMap.get("BJ"));
        log.info("根据Value获取Key: Chengdu =" + bidiMap.getKey("Chengdu"));
        bidiMap.remove("BJ");
        log.info("根据key删除数据后的Map: " + bidiMap);
        bidiMap.removeValue("Shanghai");
        log.info("根据value删除数据后的Map: " + bidiMap);
    }

    /**
     * 所谓MultiMap,就是说一个key不在是简单的指向一个对象,
     * 而是一组对象,add()和remove()的时候跟普通的Map无异,只是在get()时返回一个Collection,
     * 利用MultiMap,我们就可以很方便的往一个key上放数量不定的对象,也就实现了一对多。
     */
    @Test
    public void testMultiMap() {
        MultiMap multiMap = new MultiValueMap();
        multiMap.put("Sean", "C/C++");
        multiMap.put("Sean", "OO");
        multiMap.put("Sean", "Java");
        multiMap.put("Sean", ".NET");
        multiMap.remove("Sean", "C/C++");
        System.out.println("Sean's skill set: " + multiMap.get("Sean"));
        System.out.println(StringUtils.repeat("=", 40));
    }

    /**
     * 所谓LazyMap,意思就是这个Map中的键/值对一开始并不存在,当被调用到时才创建
     */
    @Test
    public void testLazyMap() {
        Transformer factory = new Transformer() {
            public Object transform(Object input) {
                Map map = new HashMap();
                map.put("1", 1);
                map.put("2", 2);
                map.put("NOW", new Date());
                return map;
            }
        };
        Map lazy = LazyMap.decorate(new HashMap(), factory);
        log.info(lazy.toString());
        log.info(lazy.get("NOW").toString());
        log.info(lazy.toString());
        System.out.println(StringUtils.repeat("=", 40));
    }

    @Test
    public void testMapUtils() {
//        Map<String, Object> temp = null;
//        return MapUtils.emptyIfNull(temp);
        Map<String, Object> map = new HashMap<>();
        map.put("1", "1");
        map.put("2", 2);
        map.put("3", null);
        log.info("get String类型:" + (MapUtils.getString(map, "1").equals("1")));
        log.info("get Integer类型:" + (MapUtils.getInteger(map, "2") == 2));
        log.info("get value is null:" + (MapUtils.getString(map, "3") == null));
        log.info("get key is null:" + (MapUtils.getObject(map, "4") == null));
        log.info("是否为空:" + MapUtils.isEmpty(map));
        log.info("Map类型:" + map);
        // 不可变map
        Map<String, Object> unmodifiableMap = MapUtils.unmodifiableMap(map);
        unmodifiableMap.put("1", "11");
        log.info("unmodifiableMap类型:" + unmodifiableMap);
    }

    @Test
    public void testOrderedMap() {
        OrderedMap<String, String> map = new LinkedMap<String, String>();
        map.put("One", "1");
        map.put("Two", "2");
        map.put("Three", "3");
        log.info(map.firstKey());
        log.info(map.nextKey("Two"));
        log.info(map.nextKey("One"));
    }

    /**
     * 可以计算一个对象出现在集合中的次数
     */
    @Test
    public void testHashBag() {
        Bag<String> bag = new HashBag<String>();
        bag.add("a", 2);
        bag.add("b");
        bag.add("c");
        bag.add("d", 3);
        log.info("bag: " + bag);
        log.info("d出现了 {} 次.", bag.getCount("d"));
        log.info("Bag中不重复的元素: " + bag.uniqueSet());
        bag.remove("d", 2);
        log.info("从bag中删除两个d: " + bag);
        log.info("d出现了 {} 次.", bag.getCount("d"));
        log.info("bag: " + bag);
        bag.remove("d");
        log.info("Bag中不重复的元素: " + bag.uniqueSet());
    }

    @Test
    public void testCollectionUtils() {
        // 合并list并排序
        List<String> sortedList1 = Arrays.asList("A", "C", "E");
        List<String> sortedList2 = Arrays.asList("B", "D", "F");
        log.info("list 是否为空:" + CollectionUtils.isEmpty(sortedList1));
        List<String> mergedList = CollectionUtils.collate(sortedList1, sortedList2);
        log.info("合并list:" + mergedList);
        log.info("是否包含A:" + mergedList.contains("A"));
        log.info("是否包含A和a:" + CollectionUtils.containsAll(mergedList, Arrays.asList("A", "b")));
        log.info("是否包含A或a:" + CollectionUtils.containsAny(mergedList, "A", "b"));
        List<String> list1 = Arrays.asList("A", "A", "A", "C", "B", "B");
        List<String> list2 = Arrays.asList("A", "A", "B", "B", "D");
        log.info("List1是否包含list2中的内容: " + CollectionUtils.isSubCollection(list2, list1));
        log.info("List1和list2的交集: " + CollectionUtils.intersection(list1, list2));
        log.info("List1和list2的差集: " + CollectionUtils.subtract(list1, list2));
        log.info("List1和list3的合集: " + CollectionUtils.union(list1, list2));
    }

}

IO

IO 是一个 I/O 工具集。

一、FileUtils

打开FileUtils的api文档,我们抽出一些工作中比较常用的方法,进行总结和讲解。总结如下:

cleanDirectory:清空目录,但不删除目录。

contentEquals:比较两个文件的内容是否相同。

copyDirectory:将一个目录内容拷贝到另一个目录。可以通过FileFilter过滤需要拷贝的 文件。

copyFile:将一个文件拷贝到一个新的地址。

copyFileToDirectory:将一个文件拷贝到某个目录下。

copyInputStreamToFile:将一个输入流中的内容拷贝到某个文件。

deleteDirectory:删除目录。

deleteQuietly:删除文件。

listFiles:列出指定目录下的所有文件。

openInputSteam:打开指定文件的输入流。

readFileToString:将文件内容作为字符串返回。

readLines:将文件内容按行返回到一个字符串数组中。

size:返回文件或目录的大小。

write:将字符串内容直接写到文件中。

writeByteArrayToFile:将字节数组内容写到文件中。

writeLines:将容器中的元素的toString方法返回的内容依次写入文件中。

writeStringToFile:将字符串内容写到文件中。

二、IOUtils

打开IOUtils的api文档,我们发现它的方法大部分都是重载的。所以,我们理解它的方法并不是难事。因此,对于方法的用法总结如下:

  1. buffer方法:将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小。

  2. closeQueitly方法:关闭流。

  3. contentEquals方法:比较两个流中的内容是否一致。

  4. copy方法:将输入流中的内容拷贝到输出流中,并可以指定字符编码。

    1. copyLarge方法:将输入流中的内容拷贝到输出流中,适合大于2G内容的拷贝。
  5. lineIterator方法:返回可以迭代每一行内容的迭代器。

  6. read方法:将输入流中的部分内容读入到字节数组中。

  7. readFully方法:将输入流中的所有内容读入到字节数组中。

  8. readLine方法:读入输入流内容中的一行。

  9. toBufferedInputStream,toBufferedReader:将输入转为带缓存的输入流。

  10. toByteArray,toCharArray:将输入流的内容转为字节数组、字符数组。

  11. toString:将输入流或数组中的内容转化为字符串。

  12. write方法:向流里面写入内容。

  13. writeLine方法:向流里面写入一行内容。

@Slf4j
public class CommonIOTest {

    //文件父目录
    private static final String PARENT_DIR = "C:\\Users\\huayu\\Desktop\\test";
    //文件绝对路径
    private static final String EXAMPLE_TXT_PATH = "C:\\Users\\huayu\\Desktop\\test\\commonio.txt";

    private static final String NEW_DIR = "C:\\Users\\huayu\\Desktop\\test\\newDir";

    private static final String NEW_FILE = "C:\\Users\\huayu\\Desktop\\test\\newFile.txt";

    /**
     * Utils(FileUtils,FilenameUtils,FileSystemUtils)这三个类主要提供了对文件、文件名及文件系统的操作,API非常简单,
     * 通过API名称都能知道其作用,
     *
     * @throws IOException
     */
    @Test
    public void runExample1() throws IOException {
        // FilenameUtils类示例
        log.info("获取完整路径: " + FilenameUtils.getFullPath(EXAMPLE_TXT_PATH));
        log.info("获取名称: " + FilenameUtils.getName(EXAMPLE_TXT_PATH));
        log.info("获取扩展名: " + FilenameUtils.getExtension(EXAMPLE_TXT_PATH));
        log.info("获取文件名: " + FilenameUtils.getBaseName(EXAMPLE_TXT_PATH));


        // FileUtils类示例
        // 通过FileUtils.getFile(String)创建File对象,然后根据FileUtils.lineIterator(File)
        //获取行迭代器
        File exampleFile = FileUtils.getFile(EXAMPLE_TXT_PATH);
        LineIterator iter = FileUtils.lineIterator(exampleFile);

        log.info("获取文本内容...");
        while (iter.hasNext()) {
            log.info("\t" + iter.next());
        }
        iter.close();

        // 目录是否已经包含文件
        File parent = FileUtils.getFile(PARENT_DIR);
        log.info("目录是否已经包含文件: " + FileUtils.directoryContains(parent, exampleFile));

        // IOCase类示例
        String str1 = "This is a new String.";
        String str2 = "This is another new String, yes!";
        log.info("以字符串结尾(区分大小写): " + IOCase.SENSITIVE.checkEndsWith(str1, "string."));
        log.info("以字符串结尾(不区分大小写): " + IOCase.INSENSITIVE.checkEndsWith(str1, "string."));
        log.info("字符串相等: " + IOCase.SENSITIVE.checkEquals(str1, str2));


        log.info("可用磁盘空间 (in KB): " + Files.getFileStore(Paths.get(PARENT_DIR)).getUsableSpace());
        log.info("可用磁盘空间 (in GB): " + Files.getFileStore(Paths.get(PARENT_DIR)).getUsableSpace() / 1024 / 1024 / 1024);
        FileSystems.getDefault().getFileStores();
    }

    /**
     * 文件监控器
     */
    @Test
    public void fileMonitorTest() {
        log.info("文件监测示例...");
        // FileEntry
        // 我们可以使用此类的方法监视更改并获取有关文件的信息。
        FileEntry entry = new FileEntry(FileUtils.getFile(EXAMPLE_TXT_PATH));
        log.info("监控的文件: " + entry.getFile());
        log.info("文件名: " + entry.getName());
        log.info("是否是目录?: " + entry.isDirectory());

        // 文件(目录)监控
        // 给指定目录创建观察者,并添加监听器,对事件作出响应
        File parentDir = FileUtils.getFile(PARENT_DIR);
        // 创建一个FileAlterationObserver对象,这个对象会观察这些变化。
        FileAlterationObserver observer = new FileAlterationObserver(parentDir);
        observer.addListener(new FileAlterationListenerAdaptor() {
            @Override
            public void onFileCreate(File file) {
                log.info("创建文件: " + file.getName());
            }

            @Override
            public void onFileDelete(File file) {
                log.info("删除文件: " + file.getName());
            }

            @Override
            public void onDirectoryCreate(File dir) {
                log.info("创建目录: " + dir.getName());
            }

            @Override
            public void onDirectoryDelete(File dir) {
                log.info("删除目录: " + dir.getName());
            }
        });

        // 创建一个每隔500毫秒就做一次检查的监控
        FileAlterationMonitor monitor = new FileAlterationMonitor(500, observer);
        try {
            // 调用start()方法即可开启监视器
            monitor.start();
            //启动监控后,对监控目录做一些文件操作,触发监听器
            File newDir = new File(NEW_DIR);
            File newFile = new File(NEW_FILE);

            newDir.mkdirs();
            newFile.createNewFile();

            Thread.sleep(1000);

            FileDeleteStrategy.NORMAL.delete(newDir);
            FileDeleteStrategy.NORMAL.delete(newFile);

            Thread.sleep(1000);
            // 调用stop()方法停止监视器
            monitor.stop();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 文件比较器
     */
    @Test
    public void comparatorTest() {
        log.info("文件比较器...");

        //NameFileComparator:根据文件名称排序,IOCase表示是否大小写敏感
        File parentDir = FileUtils.getFile(PARENT_DIR);
        NameFileComparator comparator = new NameFileComparator(IOCase.SENSITIVE);
        File[] sortedFiles = comparator.sort(parentDir.listFiles());

        log.info("按父目录中文件的名称排序: ");
        for (File file : sortedFiles) {
            log.info("\t" + file.getAbsolutePath());
        }

        // SizeFileComparator:根据文件大小排序,小文件在前,其构造器支持传一个boolean类型的参数,
        // true表示需要计算该目录下的目录大小
        // false表示不需要计算该目录下的目录大小
        SizeFileComparator sizeComparator = new SizeFileComparator(true);
        File[] sizeFiles = sizeComparator.sort(parentDir.listFiles());
        log.info("按父目录中文件的大小排序: ");
        for (File file : sizeFiles) {
            log.info("\t" + file.getName() + " 文件大小(kb): " + file.length());
        }

        // LastModifiedFileComparator:根据修改时间排序,最新修改排后面
        LastModifiedFileComparator lastModified = new LastModifiedFileComparator();
        File[] lastModifiedFiles = lastModified.sort(parentDir.listFiles());
        log.info("按父目录中文件的最新修改时间排序: ");
        for (File file : lastModifiedFiles) {
            Date modified = new Date(file.lastModified());
            log.info("\t" + file.getName() + " last modified on: " + modified);
        }
    }

    /**
     * 文件过滤
     */
    @Test
    public void fileFilterTest() {
        log.info("文件过滤...");
        // NameFileFilter:获取指定目录下,符合给定文件列表的文件
        //例如获取此例,获取PARENT_DIR目录下commonios和commonio.txt文件
        File dir = FileUtils.getFile(PARENT_DIR);
        String[] acceptedNames = {"commonios", "commonio.txt"};
        for (String file : Objects.requireNonNull(dir.list(new NameFileFilter(acceptedNames, IOCase.INSENSITIVE)))) {
            log.info("找到文件, 文件名: " + file);
        }

        //WildcardFileFilter:支持正则匹配,获取指定目录下,满足正则的文件
        for (String file : Objects.requireNonNull(dir.list(new WildcardFileFilter("*common*")))) {
            log.info("找到通配符文件, 文件名: " + file);
        }

        // PrefixFileFilter:获取以给定字符串为前缀的文件名
        for (String file : Objects.requireNonNull(dir.list(new PrefixFileFilter("common")))) {
            log.info("找到前缀文件, 文件名: " + file);
        }

        // SuffixFileFilter::获取以给定字符串为后缀的文件名
        for (String file : Objects.requireNonNull(dir.list(new SuffixFileFilter(".txt")))) {
            log.info("找到后缀文件, 文件名: " + file);
        }

        // OrFileFilter:支持传入多个过滤器,过滤器之间是或的关系
        for (String file : Objects.requireNonNull(dir.list(new OrFileFilter(
                new WildcardFileFilter("*ample*"), new SuffixFileFilter(".txt"))))) {
            log.info("Or, 文件名: " + file);
        }

        //AndFileFilter:支持传入多个过滤器,过滤器之间是且的关系
        for (String file : Objects.requireNonNull(dir.list(new AndFileFilter(
                new WildcardFileFilter("*ample*"),
                new NotFileFilter(new SuffixFileFilter(".txt")))))) {
            log.info("And/Not, 文件名: " + file);
        }
    }

    private static final String INPUT = "文件内容--文件内容-文件内容-文件内容--.";

    @Test
    public void teeInputStreamTest() {
        log.info("输出流示例...");
        TeeInputStream tee = null;
        try {
            // TeeInputStream能将输入流快速拷贝到输出流中
            ByteArrayInputStream in = new ByteArrayInputStream(INPUT.getBytes(StandardCharsets.UTF_8));
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            tee = new TeeInputStream(in, out, false);
            tee.read(INPUT.getBytes());
            log.info("输出流: " + out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //此处不需要关闭teeOut,当关闭teeIn时,同时会关闭teeOut
            try {
                assert tee != null;
                tee.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        TeeInputStream teeIn = null;
        TeeOutputStream teeOut = null;
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(INPUT.getBytes(StandardCharsets.UTF_8));
            // 能将输入流同时拷贝到两个输出流
            ByteArrayOutputStream out1 = new ByteArrayOutputStream();
            ByteArrayOutputStream out2 = new ByteArrayOutputStream();
            teeOut = new TeeOutputStream(out1, out2);
            teeIn = new TeeInputStream(in, teeOut, true);
            teeIn.read(INPUT.getBytes());
            log.info("输出流 1: " + out1);
            log.info("输出流 2: " + out2);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //此处不需要关闭teeOut,当关闭teeIn时,同时会关闭teeOut
            try {
                assert teeIn != null;
                teeIn.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Test
    public void FileUtilsTest() {
        File file = FileUtils.getFile(EXAMPLE_TXT_PATH);
    }
}

FileUpload

FileUpload 使得在你可以在应用和Servlet中容易的加入强大和高性能的文件上传能力。

HttpClient

Commons-HttpClient 提供了可以工作于HTTP协议客户端的一个框架。

不再被开发, 已被Apache HttpComponents项目HttpClient和HttpCore 模组取代,提供更好的性能和更大的灵活性。

Betwixt

Betwixt提供将 JavaBean 映射至 XML 文档,以及相反映射的服务。

Chain

Chain 提供实现组织复杂的处理流程的“责任链模式”。

CLI

CLI 提供针对命令行参数,选项,选项组,强制选项等的简单API。

Codec

Codec 包含一些通用的编码解码算法。包括一些语音编码器,Hex、Base64、以及URL encoder。

Configuration

Commons-Configuration 工具对各种各式的配置和参考文件提供读取帮助。

Daemon

一种 unix-daemon-like java 代码的替代机制。

DBCP

Commons-DBCP 提供数据库连接池服务。

DbUtils

DbUtils 是一个 JDBC helper 类库,完成数据库任务的简单的资源清除代码。

Digester

Commons-Digester 是一个 XML-Java对象的映射工具,用于解析 XML配置文件。

Discovery

Commons-Discovery 提供工具来定位资源 (包括类) ,通过使用各种模式来映射服务/引用名称和资源名称。

EL

Commons-EL 提供在JSP2.0规范中定义的EL表达式的解释器。

Jelly

Jelly是一个基于 XML 的脚本和处理引擎。 Jelly 借鉴了 JSP 定指标签,Velocity, Cocoon和Xdoclet中的脚本引擎的许多优点。Jelly 可以用在命令行, Ant 或者 Servlet之中。

Jexl

Jexl是一个表达式语言,通过借鉴来自于Velocity的经验扩展了JSTL定义的表达式语言。

JXPath

Commons-JXPath 提供了使用Xpath语法操纵符合Java类命名规范的 JavaBeans的工具。也支持 maps, DOM 和其他对象模型。

Latka

Commons-Latka 是一个HTTP 功能测试包,用于自动化的QA,验收和衰减测试。

Launcher

Launcher 组件是一个交叉平台的Java 应用载入器。Commons-launcher 消除了需要批处理或者Shell脚本来载入Java 类。.原始的 Java 类来自于Jakarta Tomcat 4.0 项目。

Logging

Commons-Logging 是一个各种 logging API实现的包裹类。

Math

Math 是一个轻量的,自包含的数学和统计组件,解决了许多非常通用但没有及时出现在Java标准语言中的实践问题。

Modeler

Commons-Modeler 提供了建模兼容JMX规范的Mbean的机制。

Net

Net 是一个网络工具集,基于 NetComponents 代码,包括 FTP 客户端等等。

Pool

Commons-Pool 提供了通用对象池接口,一个用于创建模块化对象池的工具包,以及通常的对象池实现。

Primitives

Commons-Primitives提供了一个更小,更快和更易使用的对Java基本类型的支持。当前主要是针对基本类型的 collection。

Validator

The commons-validator提供了一个简单的,可扩展的框架来在一个XML文件中定义校验器 (校验方法)和校验规则。支持校验规则的和错误消息的国际化。

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dushuaifeng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值