使用 Groovy 读取和写入文件

了解 Groovy 编程语言如何处理文件的读取和写入。
62 位读者喜欢这篇文章。
Woman programming

WOCinTech Chat。Opensource.com 修改。CC BY-SA 4.0

新程序员需要学习的两个常见任务是如何读取和写入存储在计算机上的文件。一些示例包括在一个应用程序中创建的数据和配置文件需要被另一个应用程序读取,或者当第三个应用程序需要将信息、警告和错误写入日志文件或保存其结果以供他人使用时。

每种语言都有几种不同的读取和写入文件的方法。本文介绍 Groovy 编程语言 中的一些细节,该语言基于 Java,但具有不同的优先级,使 Groovy 感觉更像 Python。Groovy 新手首先看到的是它比 Java 简洁得多。下一个观察结果是它是(默认情况下)动态类型的。第三个是 Groovy 具有闭包,这有点像 Java 中的 lambda,但提供对整个封闭上下文的访问(Java lambda 限制了可以访问的内容)。

我的同事 Seth Kenlon 写了关于 Java 输入和输出 (I/O) 的文章。我将从他的 Java 代码出发,向您展示如何在 Groovy 中完成。

安装 Groovy

由于 Groovy 基于 Java,因此需要安装 Java。您可以在 Linux 发行版的存储库中找到最新且不错的 Java 和 Groovy 版本。或者您可以按照 Groovy 的下载页面上的说明安装 Groovy。Linux 用户的一个不错的替代方案是 SDKMan,您可以使用它来获取多个版本的 Java、Groovy 和许多其他相关工具。对于本文,我使用的是我的发行版的 OpenJDK11 版本和 SDKMan 的 Groovy 3.0.7 版本。

使用 Groovy 读取文件

首先回顾一下 Seth 的 Java 文件读取程序

import java.io.File;
import java.util.Scanner;
import java.io.FileNotFoundException;

public class Ingest {
  public static void main(String[] args) {

      try {
          File myFile = new File("example.txt");
          Scanner myScanner = new Scanner(myFile);
          while (myScanner.hasNextLine()) {
              String line = myScanner.nextLine();
              System.out.println(line);
          }
          myScanner.close();
      } catch (FileNotFoundException ex) {
          ex.printStackTrace();
      } //try
    } //main
} //class

现在我将用 Groovy 做同样的事情

def myFile = new File('example.txt')
def myScanner = new Scanner(myFile)
while (myScanner.hasNextLine()) {
	def line = myScanner.nextLine()
	println(line)
}
myScanner.close()

Groovy 看起来像 Java,但更简洁。首先要注意的是,所有这些 import 语句都已经完成了。由于 Groovy 的部分目的是作为一种脚本语言,因此通过省略周围的 classpublic static void main 的定义,Groovy 将在后台构造这些东西。

分号也消失了。Groovy 支持使用它们,但除非您想在同一行上放置多个语句,否则不需要它们。还有单引号——Groovy 支持使用单引号或双引号来分隔字符串,这在您需要在字符串中放置双引号时很方便,就像这样

'"I like this Groovy stuff", he muttered to himself.'

另请注意,try...catch 消失了。Groovy 支持 try...catch,但不需要它,它会给出非常好的错误消息和堆栈跟踪,就像 Java 示例中的 ex.printStackTrace() 调用一样。

Groovy 在 Java 提出 var 关键字之前很久就采用了 def 关键字和从语句右侧推断类型的功能,并且 Groovy 允许在任何地方使用它。但是,除了使用 def 之外,完成主要工作的代码看起来与 Java 版本非常相似。哦,是的,除了 Groovy 还内置了这种很好的元编程能力,除其他外,它允许您编写 println() 而不是 System.out.println()。这种相似性远不止表面,它允许 Java 程序员非常快速地使用 Groovy。

就像 Python 程序员一直在寻找执行操作的 Pythonic 方式一样,有看起来像 Java 的 Groovy,然后还有……更 Groovy 的 Groovy。这解决了相同的问题,但使用 Groovy 的 with 方法使代码更 DRY(“不要重复自己”)并自动关闭输入文件

new Scanner(new File('example.txt')).with {
    while (hasNextLine()) {
      def line = nextLine()
      println(line)
    }
}

.with {} 之间的是闭包体。请注意,您不需要编写 myScanner.hasNextLine()myScanner.nextLine(),因为 with 将这些方法直接暴露给闭包体。此外,with 消除了对 myScanner.close() 进行编码的需要,因此我们实际上根本不需要声明 myScanner

运行它

$ groovy ingest1.groovy
Caught: java.io.FileNotFoundException: example.txt (No such file or directory)
java.io.FileNotFoundException: example.txt (No such file or directory)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at ingest1.run(ingest1.groovy:1)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
$

请注意“文件未找到”异常;这是因为还没有一个名为 example.txt 的文件。另请注意,这些文件来自 java.io 等。

所以我会写一些东西到那个文件中...

使用 Groovy 将数据写入文件

结合我之前分享的内容,嗯,变得“groovy”

new FileWriter("example.txt", true).with {
	write("Hello world\n")
	flush()
}

记住文件名后的 true 表示“追加到文件”,所以您可以运行几次

$ groovy exgest.groovy
$ groovy exgest.groovy
$ groovy exgest.groovy
$ groovy exgest.groovy

然后您可以使用 ingest1.groovy 读取结果

$ groovy ingest1.groovy
Hello world
Hello world
Hello world
Hello world
$

调用 flush() 是因为 with / write 组合在关闭之前没有进行刷新。 Groovy 并不总是更短!

Groovy 资源

Apache Groovy 网站有很多很棒的 文档。另一个很棒的 Groovy 资源是 Mr. Haki。学习 Groovy 的一个非常好的理由是学习 Grails,它是一个非常高效的全栈 Web 框架,建立在 Hibernate、Spring Boot 和 Micronaut 等优秀组件之上。

接下来阅读什么
标签
Chris Hermansen portrait Temuco Chile
自从 1978 年毕业于不列颠哥伦比亚大学以来,我很少没有某种计算机,自 2005 年以来一直是全职 Linux 用户,从 1986 年到 2005 年一直是全职 Solaris 和 SunOS 用户,在此之前是 UNIX System V 用户。

评论已关闭。

Creative Commons License本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。
© . All rights reserved.