问题
The question is likely VERY trivial for anyone familiar with ant, of which I only use the basics thus far.
I know how to rename files, e.g. I already use:
<copy todir="build/css/">
<fileset dir="css/">
<include name="*.css"/>
</fileset>
<globmapper from="*.css" to="*-min.css"/>
</copy>
I know how to calculate an MD5:
<checksum file="foo.bar" property="foobarMD5"/>
I don't know how to include the second into the first, to rename all those files to include their MD5 - the purpose is to serve as webbrowser cache buster. The other cache-busting option, to append "?[something]" is not as good, as is explained on some Google webmaster pages, having the MD5 as part of the name is better.
回答1:
You could do this without having to include ant contrib
. I had to implement this for work and was not allowed to introduce that extension for security reasons. The solution I came to was this:
<target name="appendMD5">
<copy todir="teststack">
<fileset dir="css/" includes="**/*.css"/>
<scriptmapper language="javascript"><![CDATA[
var File = Java.type('java.io.File');
var Files = Java.type('java.nio.file.Files');
var MessageDigest = Java.type('java.security.MessageDigest');
var DatatypeConverter = Java.type('javax.xml.bind.DatatypeConverter');
var buildDir = MyProject.getProperty('builddir');
var md5Digest = MessageDigest.getInstance('MD5');
var file = new File(buildDir, source);
var fileContents = FIles.readAllBytes(file.toPath());
var hash = DatatypeConverter.printHexBinary(md5Digest.digest(fileContents));
var baseName = source.substring(0, source.lastIndexOf('.'));
var extension = source.substring(source.lastIndexOf('.'));
self.addMappedName(baseName + '-' + hash + extension);
]]></scriptmapper>
</copy>
</target>
It is worth noting that I wrote this for Java 8 but with some minor tweaks it could work on Java 7. Sadly this won't work for earlier versions of Java without more effort.
回答2:
I managed to produce a somewhat strange solution using for from ant contrib.
But you have to install ant contrib first.
The copy
in the sequential
does not seem to accept/evaluate mappers
(it wouldn't work, I tried with ant 1.7.0), so I had to create an extra move
with a filtermapper to create the results.
It does the following:
- for each file create an md5sum and save it in property foobarMD5
- the property has to be unset before each iteration
- I create a new file in the same
dir
namedexample.java_foobarMD5.java
(Notice that the filename contains the fileextension) - I move all files with
.java_
in its name to a new Folder and remove the.java_
I leave this example with .java.
<for param="file">
<path>
<fileset dir="src/" includes="**/*.java"/>
</path>
<sequential>
<echo>Letter @{file}</echo>
<var name="foobarMD5" unset="true"/>
<checksum file="@{file}" property="foobarMD5"/>
<echo>${foobarMD5}</echo>
<copy file="@{file}" tofile="@{file}_${foobarMD5}.java"/>
</sequential>
</for>
<move todir="teststack" verbose="true">
<fileset dir="src/">
<include name="**/*java_*"/>
</fileset>
<filtermapper>
<replacestring from=".java_" to="-"/>
</filtermapper>
</move>
来源:https://stackoverflow.com/questions/8724727/ant-rename-files-to-include-their-md5