一:Java 与 Groovy 读文件操作比较
Groovy 对 java.io.File 进行了扩展,增加了一些接受闭包参数和简化文件操作的方法。作为对比,我们还是先来看看 java 中读取文件的两种常方法,分别是行读取和字节缓冲区读取:
01. //--BufferedReader 行读取 02. BufferedReader br = null ; 03. try { 04. br = new BufferedReader( new FileReader( "foo.txt" )); 05. List<String> content = new ArrayList<String>(); 06. String line = null ; 07. while ((line=br.readLine())!= null ){ 08. content.add(line); 09. } 10. } catch (FileNotFoundException e) { 11. } catch (IOException e){ 12. } finally { 13. if (br != null ){ 14. try { 15. br.close(); 16. } catch (IOException e) { 17. } 18. } 19. } |
01. //--借助于 buffer 缓冲区来读字节 02. InputStream is = null ; 03. try { 04. is = new FileInputStream( "foo.txt" ); 05. StringBuffer content = new StringBuffer(); 06. int read = - 1 ; 07. byte [] buffer = new byte [ 1024 ]; 08. while ((read=is.read(buffer))!=- 1 ){ 09. content.append( new String(buffer, 0 ,read)); 10. } 11. } catch (FileNotFoundException e) { 12. } catch (IOException e){ 13. } finally { 14. if (is != null ){ 15. try { 16. is.close(); 17. } catch (IOException e) { 18. } 19. } 20. } |
从上面可看到,采用 Java 传统方式来读取文件内容,不仅代码行多,而且还必须自己用 try/catch/finally 来处理异常和资源的关闭。现在马上来看看 Groovy 完成以上工作的代码是怎么的,只要一行代码:
1.
text =
new
File(
"foo.txt"
).
getText
();
不需要 Reader 或 Inputstream、不用关闭语名和异常处理。我们所要做的就是编写业务逻辑,剩下的工作 Groovy 会帮你料理的。当然,如果文件找不到,也是会出现 java.io.FileNotFoundException 异常的。你可以捕获这个要处理的异常,但仍然不必担心资源的释放。
1.
try
{
2.
text =
new
File(
"foo.txt"
).
getText
();
3.
}
catch
(Exception e){
4.
}
至于写文件,Groovy 的表现也比较抢眼。下面我们来体验一下 Groovy 对 java.io.File 扩展的几个方法的使用。关于 File 的所有扩展方法的使用请参考 Groovy JDK -- http://groovy.codehaus.org/groovy-jdk/ 中 java.io.File(http://groovy.codehaus.org/groovy-jdk/java/io/File.html) 部分。
二:Groovy 对 java.io.File 扩展方法举例
1. eachLine -- 打开和读取文件的每一行
1.
new
File(
"foo.txt"
).
eachLine
{
2.
println
it.toUpperCase();
3.
}
2. readLines -- 其作用基本与 eachLine 相同,但它不接受闭包为参数,而是把文件行读到一个 List 中
1.
lineList =
new
File(
"foo.txt"
).readLines();
2.
lineList.
each
{
3.
println
it.toUpperCase();
4.
}
3. splitEachLine -- 读取文件的每一行,然后对行以指定分隔符分割成数组。不用再多说了,这个方法对处理 CSV 文件那可是相当的高效。
1.
lineList =
new
File(
"foo.csv"
).
splitEachLine
(
","
) {
2.
println
"name=${it[0]} balance=${it[1]}"
;
3.
}
4. eachByte -- 处理二进制文件,以字节级访问文件,这个方法相当于 eachLine() 方法。
1.
new
File(
"foo.bin"
).eachByte {
print
it; }
5. readBytes -- 自然,处理二进制文件,以字节级访问文件,这个方法相当于 readLines() 方法了
1.
byteList =
new
File(
"foo.bin"
).
readBytes
();
2.
byteList.
each
{
3.
println
it;
4.
}
6. write -- Groovy 用这个方法写文件真是太直观了
1.
new
File(
"foo.txt"
).
write
(
"testing testing"
);
2.
3.
new
File(
"foo.txt"
).
write
(
""
"
4.
This is
5.
just a test file
6.
to play with
7.
""
");
以上使用了三重引用语法,其中的文本保留格式的写入到文件中。注意上面写法在文件首尾都会有一个空行,除非起始和结束字符都要紧贴 """;还有上面方法写的文件用词本打开会是挤在一行,用 editplus 打开是多行,因为它采用的是 linux 下的 /n 换行,而不是 windows 下的 /r/n 换行。、
7. append -- 与 write 覆写文件不同,append 是在文件后追加内容
1.
new
File(
"foo.txt"
).
append
(
""
"/
2.
This is
3.
just a test file
4.
to play withff
5.
""
"
6.
);
8. eachFile -- 功能上类似 java.io.File 的 listFiles() 方法。用来列举路径中的每个文件(包括目录),传给闭包处理
1.
new
File(
"."
).
eachFile
{
//这里的 File 表示的是一个路径
2.
println
it.getName();
//eachFile() 列出的每一项是一个 File 实例
3.
}
9. eachFileRecurse -- 以深度优先的方式递归遍历路径,列出文件(包括目录),传给闭包处理
1.
new
File(
"."
).
eachFileRecurse
{
//这里的 File 表示的是一个路径
2.
println
it.getPath();
//eachFile() 列出的每一项是一个 File 实例
3.
}
10. …… 再重复一下,其他 Groovy 对 java.io.File 的扩展方法请参考 http://groovy.codehaus.org/groovy-jdk/java/io/File.html。如 eachDir()、eachDirMatch()、eachDirRecurse()、eachFileMatch()、filterLine()、newInputStream()、newOutputStream()、newReader()、newPrintWriter()、withInputStream()、withOutputStream()、withReader()、withPrintWriter() 等等。还要留意一下有一些方法是可以指定字符集的。
参考:1. 《Java 脚本编程语言、框架与模式》第 4 章