Apache Commons IO是Apache基金会创建并维护的Java函数库。它提供了许多类使得开发者的常见任务变得简单,同时减少重复(boiler-plate)代码,这些代码可能遍布于每个独立的项目中,你却不得不重复的编写。这些类由经验丰富的开发者维护,对各种问题的边界条件考虑周到,并持续修复相关bug。
在下面的例子中,我们会向你演示一些不同功能的方法,这些功能都是在org.apache.commons.io包下。Apache Commons IO 是一个巨大工程,我们不会深入去剖析它的底层原理,但是会演示一些比较常用的例子,不管你是不是新手,相信这些例子都会对你有所帮助。
1. Apache Commons IO 示例
我们分别会用几段代码来演示下面的功能,每部分功能都代表Apache Commons IO所覆盖的一个单独领域,具体如下:
- 工具类
- 输入
- 输出
- 过滤器
- 比较器
- 文件监控器
为了更方便读者进行理解,我们会把创建的每个类的输出进行单独展示。并且会把示例中功能演示所用到的到文件放到工程目录(ExampleFolder目录)中。
注意:为了能使用org.apache.commons.io中的功能,你首先需要下载jar包(请点击这里),并且将jar包添加到Eclipse工程的编译路径下,右键点工程文件夹 -> Build Path -> Add external archives。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
public
class
ApacheCommonsExampleMain {
public
static
void
main(String[] args) {
UtilityExample.runExample();
FileMonitorExample.runExample();
FiltersExample.runExample();
InputExample.runExample();
OutputExample.runExample();
ComparatorExample.runExample();
}
}
|
这个main方法会运行所有的示例,你可以将其他行的代码注释来执行你想要的示例。
1.1 Utility Classes
FilenameUtils:
这个工具类是用来处理文件名(译者注:包含文件路径)的,他可以轻松解决不同操作系统文件名称规范不同的问题(比如windows和Unix)(在Unix系统以及Linux系统中文件分隔符是“/”,不支持”\“,windows中支持”\“以及”/“)。
FileUtils:
提供文件操作(移动文件,读取文件,检查文件是否存在等等)的方法。
IOCase:
提供字符串操作以及比较的方法。
FileSystemUtils:提供查看指定目录剩余空间的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
import
java.io.File;
import
java.io.IOException;
import
org.apache.commons.io.FileSystemUtils;
import
org.apache.commons.io.FileUtils;
import
org.apache.commons.io.FilenameUtils;
import
org.apache.commons.io.LineIterator;
import
org.apache.commons.io.IOCase;
public
final
class
UtilityExample {
// We are using the file exampleTxt.txt in the folder ExampleFolder,
// and we need to provide the full path to the Utility classes.
private
static
final
String EXAMPLE_TXT_PATH =
"C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleTxt.txt"
;
private
static
final
String PARENT_DIR =
"C:UsersLilykosworkspaceApacheCommonsExample"
;
public
static
void
runExample()
throws
IOException {
System.out.println(
"Utility Classes example..."
);
// FilenameUtils
System.out.println(
"Full path of exampleTxt: "
+
FilenameUtils.getFullPath(EXAMPLE_TXT_PATH));
System.out.println(
"Full name of exampleTxt: "
+
FilenameUtils.getName(EXAMPLE_TXT_PATH));
System.out.println(
"Extension of exampleTxt: "
+
FilenameUtils.getExtension(EXAMPLE_TXT_PATH));
System.out.println(
"Base name of exampleTxt: "
+
FilenameUtils.getBaseName(EXAMPLE_TXT_PATH));
// FileUtils
// We can create a new File object using FileUtils.getFile(String)
// and then use this object to get information from the file.
File exampleFile = FileUtils.getFile(EXAMPLE_TXT_PATH);
LineIterator iter = FileUtils.lineIterator(exampleFile);
System.out.println(
"Contents of exampleTxt..."
);
while
(iter.hasNext()) {
System.out.println(
"t"
+ iter.next());
}
iter.close();
// We can check if a file exists somewhere inside a certain directory.
File parent = FileUtils.getFile(PARENT_DIR);
System.out.println(
"Parent directory contains exampleTxt file: "
+
FileUtils.directoryContains(parent, exampleFile));
// IOCase
String str1 =
"This is a new String."
;
String str2 =
"This is another new String, yes!"
;
System.out.println(
"Ends with string (case sensitive): "
+
IOCase.SENSITIVE.checkEndsWith(str1,
"string."
));
System.out.println(
"Ends with string (case insensitive): "
+
IOCase.INSENSITIVE.checkEndsWith(str1,
"string."
));
System.out.println(
"String equality: "
+
IOCase.SENSITIVE.checkEquals(str1, str2));
// FileSystemUtils
System.out.println(
"Free disk space (in KB): "
+ FileSystemUtils.freeSpaceKb(
"C:"
));
System.out.println(
"Free disk space (in MB): "
+ FileSystemUtils.freeSpaceKb(
"C:"
) /
1024
);
}
}
|
输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
Utility Classes example...
Full path of exampleTxt: C:UsersLilykosworkspaceApacheCommonsExampleExampleFolder
Full name of exampleTxt: exampleTxt.txt
Extension of exampleTxt: txt
Base name of exampleTxt: exampleTxt
Contents of exampleTxt...
This is an example text file.
We will use it
for
experimenting with Apache Commons IO.
Parent directory contains exampleTxt file:
true
Ends with string (
case
sensitive):
false
Ends with string (
case
insensitive):
true
String equality:
false
Free disk space (in KB):
32149292
Free disk space (in MB):
31395
|
1.2 文件监控器
org.apache.commons.io.monitor包下的类包含的方法可以获取文件的指定信息,不过更重要的是,它可以创建处理器(handler)来跟踪指定文件或目录的变化并且可以在文件或目录发生变化的时候进行一些操作。让我们来看看下面的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
import
java.io.File;
import
java.io.IOException;
import
org.apache.commons.io.FileDeleteStrategy;
import
org.apache.commons.io.FileUtils;
import
org.apache.commons.io.monitor.FileAlterationListenerAdaptor;
import
org.apache.commons.io.monitor.FileAlterationMonitor;
import
org.apache.commons.io.monitor.FileAlterationObserver;
import
org.apache.commons.io.monitor.FileEntry;
public
final
class
FileMonitorExample {
private
static
final
String
EXAMPLE_PATH =
"C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleFileEntry.txt"
;
private
static
final
String
PARENT_DIR =
"C:UsersLilykosworkspaceApacheCommonsExampleExampleFolder"
;
private
static
final
String
NEW_DIR =
"C:UsersLilykosworkspaceApacheCommonsExampleExampleFoldernewDir"
;
private
static
final
String
NEW_FILE =
"C:UsersLilykosworkspaceApacheCommonsExampleExampleFoldernewFile.txt"
;
public
static
void
runExample() {
System.out.println(
"File Monitor example..."
);
// FileEntry
// We can monitor changes and get information about files
// using the methods of this class.
FileEntry entry =
new
FileEntry(FileUtils.getFile(EXAMPLE_PATH));
System.out.println(
"File monitored: "
+ entry.getFile());
System.out.println(
"File name: "
+ entry.getName());
System.out.println(
"Is the file a directory?: "
+ entry.isDirectory());
// File Monitoring
// Create a new observer for the folder and add a listener
// that will handle the events in a specific directory and take action.
File parentDir = FileUtils.getFile(PARENT_DIR);
FileAlterationObserver observer =
new
FileAlterationObserver(parentDir);
observer.addListener(
new
FileAlterationListenerAdaptor() {
@Override
public
void
onFileCreate(File file) {
System.out.println(
"File created: "
+ file.getName());
}
@Override
public
void
onFileDelete(File file) {
System.out.println(
"File deleted: "
+ file.getName());
}
@Override
public
void
onDirectoryCreate(File dir) {
System.out.println(
"Directory created: "
+ dir.getName());
}
@Override
public
void
onDirectoryDelete(File dir) {
System.out.println(
"Directory deleted: "
+ dir.getName());
}
});
// Add a monior that will check for events every x ms,
// and attach all the different observers that we want.
FileAlterationMonitor monitor =
new
FileAlterationMonitor(
500
, observer);
try
{
monitor.start();
// After we attached the monitor, we can create some files and directories
// and see what happens!
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
);
monitor.stop();
}
catch
(IOException e) {
e.printStackTrace();
}
catch
(InterruptedException e) {
e.printStackTrace();
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
输出
1
2
3
4
5
6
7
8
|
File Monitor example...
File monitored: C:UsersLilykosworkspaceApacheCommonsExampleExampleFolderexampleFileEntry.txt
File name: exampleFileEntry.txt
Is the file a directory?:
false
Directory created: newDir
File created: newFile.txt
Directory deleted: newDir
File deleted: newFile.tx
|
让我们来看看这里发生了什么,我们使用org.apache.commons.io.monitor包下的类创建了一个处理器来监听一些特定的事件(在上面的例子中就是我们对文件或目录所做的所有操作事件),为了获得这些信息,我们需要做以下几步操作:
1、创建一个File对象,这个对象指向我们需要监听变化的目录。
2、创建一个FileAlterationObserver对象,这个对象会观察这些变化。
3、通过调用addListener()方法,为observer对象添加一个 FileAlterationListenerAdaptor对象。你可以通过很多种方式来创建一个适配器,在我们的例子中我们使用内部类的方式进行创建并且只实现其中的一部分方法(只需要实现我们例子中需要用的方法即可)。
4、创建一个FileAlterationMonitor 对象,将已经创建好的observer对象添加其中并且传入时间间隔参数(单位是毫秒)。
1.3 过滤器
过滤器可以以组合的方式使用并且它的用途非常多样。它可以轻松的区分不同的文件并且找到满足我们条件的文件。我们可以组合不同的过滤器来执行文件的逻辑比较并且精确的获取我们所需要文件,而无需使用冗余的字符串比较来寻找我们的文件。
FiltersExample.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
import
java.io.File;
import
org.apache.commons.io.FileUtils;
import
org.apache.commons.io.IOCase;
import
org.apache.commons.io.filefilter.AndFileFilter;
import
org.apache.commons.io.filefilter.NameFileFilter;
import
org.apache.commons.io.filefilter.NotFileFilter;
import
org.apache.commons.io.filefilter.OrFileFilter;
import
org.apache.commons.io.filefilter.PrefixFileFilter;
import
org.apache.commons.io.filefilter.SuffixFileFilter;
import
org.apache.commons.io.filefilter.WildcardFileFilter;
public
final
class
FiltersExample {
private
static
final
String PARENT_DIR =
"C:UsersLilykosworkspaceApacheCommonsExampleExampleFolder"
;
public
static
void
runExample() {
System.out.println(
"File Filter example..."
);
// NameFileFilter
// Right now, in the parent directory we have 3 files:
// directory example
// file exampleEntry.txt
// file exampleTxt.txt
// Get all the files in the specified directory
// that are named "example".
File dir = FileUtils.getFile(PARENT_DIR);
String[] acceptedNames = {
"example"
,
"exampleTxt.txt"
};
for
(String file: dir.list(
new
NameFileFilter(acceptedNames, IOCase.INSENSITIVE))) {
System.out.println(
"File found, named: "
+ file);
}
//WildcardFileFilter
// We can use wildcards in order to get less specific results
// ? used for 1 missing char
// * used for multiple missing chars
for
(String file: dir.list(
new
WildcardFileFilter(
"*ample*"
))) {
System.out.println(
"Wildcard file found, named: "
+ file);
}
// PrefixFileFilter
// We can also use the equivalent of startsWith
// for filtering files.
for
(String file: dir.list(
new
PrefixFileFilter(
"example"
))) {
System.out.println(
"Prefix file found, named: "
+ file);
}
// SuffixFileFilter
// We can also use the equivalent of endsWith
// for filtering files.
for
(String file: dir.list(
new
SuffixFileFilter(
".txt"
))) {
System.out.println(
"Suffix file found, named: "
+ file);
}
// OrFileFilter
// We can use some filters of filters.
// in this case, we use a filter to apply a logical
// or between our filters.
for
(String file: dir.list(
new
OrFileFilter(
new
WildcardFileFilter(
"*ample*"
),
new
SuffixFileFilter(
".txt"
)))) {
System.out.println(
"Or file found, named: "
+ file);
}
// And this can become very detailed.
// Eg, get all the files that have "ample" in their name
// but they are not text files (so they have no ".txt" extension.
for
(String file: dir.list(
new
AndFileFilter(
// we will match 2 filters...
new
WildcardFileFilter(
"*ample*"
),
// ...the 1st is a wildcard...
new
NotFileFilter(
new
SuffixFileFilter(
".txt"
))))) {
// ...and the 2nd is NOT .txt.
System.out.println(
"And/Not file found, named: "
+ file);
}
}
}
|
输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
File Filter example...
File found, named: example
File found, named: exampleTxt.txt
Wildcard file found, named: example
Wildcard file found, named: exampleFileEntry.txt
Wildcard file found, named: exampleTxt.txt
Prefix file found, named: example
Prefix file found, named: exampleFileEntry.txt
|