最近,我一直在研究Groovy如何简化略微笨重的Java。在本文中,我通过创建一个分析我的音乐目录的工具来开始一个简短的系列,演示Groovy脚本。在本文中,我将演示groovy.File类如何扩展和压缩java.File并简化其使用。这为查看音乐文件夹的内容提供了一个框架,以确保预期的内容(例如cover.jpg文件)就位。我使用JAudiotagger库来分析音乐文件的标签。安装Java和GroovyGroovy是基于Java的,需要安装Java。最新且稳定的Java和Groovy版本可能在您的Linux发行版的存储库中。Groovy也可以直接从Apache基金会网站安装。Linux用户的一个不错选择是SDKMan,它可用于获取多个版本的Java、Groovy和许多其他相关工具。对于本文,我使用以下SDK版本:Java:OpenJDK11从11.0.12版开始-打开Groovy:3.0.8版音乐元数据最近,我重新发明了我消费音乐的方式。我决定使用优秀的开源Cantata音乐播放器,它是开源MPD音乐播放器的前端。我所有的电脑音乐都存储在/var/lib/mpd/music目录中。music目录下有artist子目录,每个artist子目录下有album子目录,里面有音乐文件,cover.jpg,偶尔还有PDF格式的内页说明。我的绝大多数音乐文件都是FLAC格式,少数是MP3格式,可能还有一小部分是OGG格式。我选择JAudiotagger库的原因之一是它可以透明地处理不同的标记格式。当然,JAudiotagger是开源的!那么查看音频标签有什么意义呢?根据我的经验,音频标签的管理非常糟糕。(提到音频标签,)想到“粗心”一词。这是标签本身的一个真正问题,也可能是我自己的迂腐倾向。不管怎样,这是一个重要的问题,可以通过使用Groovy和JAudiotagger来解决。不过,它不仅适用于音乐收藏。许多其他现实世界的问题也适用,例如需要进入文件系统中的目录树以处理在那里找到的内容。使用Groovy脚本这是此任务所需的基本代码。我在脚本中包含了反映(相对缩写的)“评论提醒”的评论,我通常对自己保密://定义音乐库目录defmusicLibraryDirName='/var/lib/mpd/music'//输出CSV文件标题行println"artistDir|albumDir|contentFile"//遍历音乐库目录中的每个目录//这一层应该是艺术家目录newFile(musicLibraryDirName).eachDir{artistDir->//遍历艺术家目录中的每个目录//这个level应为专辑目录artistDir.eachDir{albumDir->//遍历专辑目录中的每个目录//这应该是内容//或相关内容(例如`cover.jpg`,页面描述中的PDF格式)albumDir.eachFile{contentFile->println"$artistDir.name|$albumDir.name|$contentFile.name"}}}如上所述,我使用groovy.File在目录树中移动。具体来说:第7行创建了一个新的groovy.File对象并在其上调用了groovy.File.eachDir(),第7行的{和第18行末尾的}之间的代码是传递给groovy.Colsue的参数每个目录()。这意味着eachDir()为它在目录中找到的每个子目录执行该代码。这类似于Javalambda(也称为“匿名函数”)。Groovy闭包不像lambda那样限制对调用环境的访问(在最新版本的Groovy中,如果您愿意,也可以使用Javalambda)。如上所述,音乐库目录中的子目录应该是艺术家目录(例如,“IronButterfly”或“GiacomoPuccini”),因此artistDir是eachDir()传递给闭包的参数。第10行为每个artistDir调用eachDir(),第10行的{和第17行的}之间的代码形成另一个处理albumDir的闭包。在第14行,对每个albumDir调用了eachFile(),第14行的{和第16行的}之间的代码构成了处理专辑内容的三级闭包。在本文的范围内,我需要对每个文件做的唯一一件事就是开始构建信息表,我将其创建为竖线分隔的CSV文件,可以将其导入LibreOffice或OfficeOnly或任何其他电子表格。现在,代码输出前三列:艺术家目录名称、专辑目录名称和内容文件名称(类似地,第2行输出CSV标题行)。在我的Linux笔记本电脑上运行它会产生以下输出:$groovyTagAnalyzer.groovy|headartistDir|albumDir|contentFileHabibKoite&Bamada|Afriki|02-Ntesse.flacHabibKoite&Bamada|Afriki|08-NTeri.flacHabibKoite&Bamada|Afriki|01-Namania.flacHabibKoite&Bamada|Afriki|07-Barra.flacHabibKoite&Bamada|Afriki|playlist.m3uHabibKoite&Bamada|Afriki|04-Fimani.flacHabibKoite&Bamada|Afriki|10-Massake.flacHabibKoite&Bamada|Afriki||Afriki|11-Titati.flacHabibKoite&Bamada|Afriki|03–Africa.flac[...]RichardCrandell|弹簧钢|04-日本摇篮曲[RichardCrandell].flacRichardCrandell|弹簧钢|弹簧钢.pdfRichardCrandell|SpringSteel|03-ZenDagger[RichardCrandell].flacRichardCrandell|SpringSteel|cover.jpg$在性能方面:$timegroovyTagAnalyzer.groovy|wc-l9870real0m1.482suser0m4.392ssys0m0.230s$又好又快。它在1秒半内处理了将近10,000个文件!对我来说足够快了。可观的性能、紧凑和可读的代码,有什么不喜欢的?
