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文档,我们发现它的方法大部分都是重载的。所以,我们理解它的方法并不是难事。因此,对于方法的用法总结如下:
-
buffer方法:将传入的流进行包装,变成缓冲流。并可以通过参数指定缓冲大小。
-
closeQueitly方法:关闭流。
-
contentEquals方法:比较两个流中的内容是否一致。
-
copy方法:将输入流中的内容拷贝到输出流中,并可以指定字符编码。
- copyLarge方法:将输入流中的内容拷贝到输出流中,适合大于2G内容的拷贝。
-
lineIterator方法:返回可以迭代每一行内容的迭代器。
-
read方法:将输入流中的部分内容读入到字节数组中。
-
readFully方法:将输入流中的所有内容读入到字节数组中。
-
readLine方法:读入输入流内容中的一行。
-
toBufferedInputStream,toBufferedReader:将输入转为带缓存的输入流。
-
toByteArray,toCharArray:将输入流的内容转为字节数组、字符数组。
-
toString:将输入流或数组中的内容转化为字符串。
-
write方法:向流里面写入内容。
-
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文件中定义校验器 (校验方法)和校验规则。支持校验规则的和错误消息的国际化。