我正在为OpenCMS项目的Ant构建期间编写manifest.xml
文件。
我需要能够在文件上提取文件的创建日期和上次修改日期。 (尽管当前进程正在为每个文件提供Wed, 31 Dec 1969 19:00:00 EST
的时间戳 - 至少在运行构建时的Windows机器上。)
有没有办法可以提取Ant中文件的创建日期时间戳?我使用标准的Ant任务和Ant-Contrib任务。
答案 0 :(得分:3)
我有这个工作。
正如Mark O'Connor指出的那样,您无法从早期版本的Java获取文件创建时间。但是,用于此任务的原始Java程序在创建日期和最后修改日期 1 中使用lastModified方法。我做得很好。
我创建了一个<scriptdef>
来从文件中提取上次修改日期。在Java 1.6及更高版本中,您可以直接访问Rhino JavaScript库,因此不再需要BeanShell库。
<scriptdef name="file.mdate" language="javascript">
<attribute name="file"/>
<attribute name="property"/>
file_name = attributes.get("file");
property_to_set = attributes.get("property");
file = new java.io.File(file_name);
file_date = file.lastModified();
date_format = new java.text.SimpleDateFormat("EEE, dd MMM YYYY HH:mm:ss zzz");
formated_date = date_format.format(new java.util.Date(file_date));
project.setNewProperty(property_to_set, formated_date);
</scriptdef>
一旦定义,我就可以将它用作Ant任务:
<file.mdate
file="${file.name}"
property="file.modified.date"/>
<echo>The file "${file}" was modified on ${file.modified.date}</echo>
答案 1 :(得分:2)
这取决于你的操作系统,f.e。 Unix不存储文件创建时间see details here
两种可能的解决方案:
解决方案1,仅在Windows上使用Java&gt; = 6,无需插件
<project>
<!-- Works on Windows only, uses the jdk builtin
rhino javascript engine (since jdk6)
use dir command without /T:C to get lastmodificationtime
-->
<macrodef name="getFileTimes">
<attribute name="dir" />
<attribute name="file" />
<attribute name="setprop" default="@{file}_ctime" />
<sequential>
<exec executable="cmd" dir="@{dir}" outputproperty="@{setprop}">
<arg value="/c" />
<arg line="dir @{file} /T:C|find ' @{file}'" />
</exec>
<script language="javascript">
tmp = project.getProperty("@{setprop}").split("\\s+") ;
project.setProperty("@{setprop}", tmp[0] + "/" + tmp[1]) ;
</script>
</sequential>
</macrodef>
<getFileTimes dir="C:/tmp" file="bookmarks.html" />
<echo>
$${bookmarks.html_ctime} => ${bookmarks.html_ctime}
</echo>
</project>
解决方案2,需要Java 7和groovy-all-x.x.x.jar(包含在groovy binary release中)
根据自己的喜好调整SimpleDateFormat。
在Unix文件系统上询问创建时间时,您将获得最后的修改时间。
<project>
<taskdef name="groovy" classname="org.codehaus.groovy.ant.Groovy"/>
<!-- Solution for Java 7, uses the nio package
needs groovy-all-2.1.0.jar
-->
<macrodef name="getFileTimes">
<attribute name="file"/>
<attribute name="ctimeprop" default="@{file}_ctime"/>
<attribute name="mtimeprop" default="@{file}_mtime"/>
<sequential>
<groovy>
import java.nio.file.*
import java.nio.file.attribute.*
import java.text.*
import java.util.date.*
Path path = Paths.get("@{file}")
BasicFileAttributeView view = Files.getFileAttributeView(path, BasicFileAttributeView.class)
BasicFileAttributes attributes = view.readAttributes()
lastModifiedTime = attributes.lastModifiedTime()
createTime = attributes.creationTime()
DateFormat df = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ss", Locale.US)
df.format(new Date(createTime.toMillis()))
properties.'@{ctimeprop}' = df.format(new Date(createTime.toMillis()))
properties.'@{mtimeprop}' = df.format(new Date(lastModifiedTime.toMillis()))
</groovy>
</sequential>
</macrodef>
<getFileTimes file="C:/tmp/bookmarks.html"/>
<echo>
$${C:/tmp/bookmarks.html_ctime} => ${C:/tmp/bookmarks.html_ctime}
$${C:/tmp/bookmarks.html_mtime} => ${C:/tmp/bookmarks.html_mtime}
</echo>
</project>
我也尝试使用内置的javascript引擎,但是我遇到了类似的错误:
sun.org.mozilla.javascript.internal.EvaluatorException: missing name after . operator
IMO,对于使用javascript <script language="javascript">
的简单事情就足够了,但是如果你需要导入java包等..那就是PITA。 Groovy很简单。
答案 2 :(得分:0)
问题是标准Java File对象仅支持返回上次修改日期的方法:
使用新的NIO类在Java 7中解决了这个问题:
显然,要在ANT中利用这一点,您需要编写自定义任务或嵌入脚本。
答案 3 :(得分:0)
David W.s answer中存在错误: 它不适用于第二次运行,因为该属性在第二次运行时不会被覆盖。
更改:project.setNewProperty
应为project.setProperty
完整的代码段:
<scriptdef name="filedate" language="javascript">
<attribute name="file"/>
<attribute name="property"/>
<![CDATA[
file_name = attributes.get("file");
property_to_set = attributes.get("property");
file = new java.io.File(file_name);
file_date = file.lastModified();
date_format = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
formated_date = date_format.format(new java.util.Date(file_date));
project.setProperty(property_to_set, formated_date);
]]>
</scriptdef>