How do I get the last modification time of a Java resource?

落花浮王杯 提交于 2020-01-24 02:08:48

问题


Can someone please tell me a reliable way to get the last modification time of a Java resource? The resource can be a file or an entry in a JAR.


回答1:


If you with "resource" mean something reachable through Class#getResource or ClassLoader#getResource, you can get the last modified time stamp through the URLConnection:

URL url = Test.class.getResource("/org/jdom/Attribute.class");
System.out.println(new Date(url.openConnection().getLastModified()));

Be aware that getLastModified() returns 0 if last modified is unknown, which unfortunately is impossible to distinguish from a real timestamp reading "January 1st, 1970, 0:00 UTC".




回答2:


The problem with url.openConnection().getLastModified() is that getLastModified() on a FileURLConnection creates an InputStream to that file. So you have to call urlConnection.getInputStream().close() after getting last modified date. In contrast JarURLConnection creates the input stream when calling getInputStream().




回答3:


Apache Commons VFS provides a generic way of interacting with files from different sources. FileObject.getContent() returns a FileContent object which has a method for retreiving the last modified time.

Here is a modified example from the VFS website:

import org.apache.commons.vfs.FileSystemManager;
import org.apache.commons.vfs.FileObject;
...
FileSystemManager fsManager = VFS.getManager();
FileObject jarFile = fsManager.resolveFile( "jar:lib/aJarFile.jar" );
System.out.println( jarFile.getName().getBaseName() + " " + jarFile.getContent().getLastModifiedTime() );

// List the children of the Jar file
FileObject[] children = jarFile.getChildren();
System.out.println( "Children of " + jarFile.getName().getURI() );
for ( int i = 0; i < children.length; i++ )
{
    System.out.println( children[ i ].getName().getBaseName() + " " + children[ i ].getContent().getLastModifiedTime());
}



回答4:


I am currently using the following solution. The solution is the same like most of the other solutions in its initial steps, namely some getResource() and then openConnection().

But when I have the connection I am using the following code:

/**
 * <p>Retrieve the last modified date of the connection.</p>
 *
 * @param con The connection.
 * @return The last modified date.
 * @throws IOException Shit happens.
 */
private static long getLastModified(URLConnection con) throws IOException {
    if (con instanceof JarURLConnection) {
        return ((JarURLConnection)con).getJarEntry().getTime();
    } else {
        return con.getLastModified();
    }
}

The above code works on android and non-android, it returns the last modified date of the entry inside the ZIP if the resources is found inside an archive, otherwise it returns what it gets from the connection.

Bye

P.S.: The code still needs some brushing, there are some border cases where getJarEntry() is null.




回答5:


Here is my code for getting the last modification time of your JAR file or compiled class (when using an IDE).

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.attribute.FileTime;
import java.text.DateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

public class ProgramBuildTime
{
    private static String getJarName()
    {
        Class<?> currentClass = getCurrentClass();
        return new File(currentClass.getProtectionDomain()
                .getCodeSource()
                .getLocation()
                .getPath())
                .getName();
    }

    private static Class<?> getCurrentClass()
    {
        return new Object() {}.getClass().getEnclosingClass();
    }

    private static boolean runningFromJAR()
    {
        String jarName = getJarName();
        return jarName.endsWith(".jar");
    }

    public static String getLastModifiedDate() throws IOException, URISyntaxException
    {
        Date date;

        if (runningFromJAR())
        {
            String jarFilePath = getJarName();
            try (JarFile jarFile = new JarFile(jarFilePath))
            {
                long lastModifiedDate = 0;

                for (Enumeration<JarEntry> entries = jarFile.entries(); entries.hasMoreElements(); )
                {
                    String element = entries.nextElement().toString();
                    ZipEntry entry = jarFile.getEntry(element);
                    FileTime fileTime = entry.getLastModifiedTime();
                    long time = fileTime.toMillis();

                    if (time > lastModifiedDate)
                    {
                        lastModifiedDate = time;
                    }
                }

                date = new Date(lastModifiedDate);
            }
        } else
        {
            Class<?> currentClass = getCurrentClass();
            URL resource = currentClass.getResource(currentClass.getSimpleName() + ".class");

            switch (resource.getProtocol())
            {
                case "file":
                    date = new Date(new File(resource.toURI()).lastModified());
                    break;

                default:
                    throw new IllegalStateException("No matching protocol found!");
            }
        }

        DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
        return dateFormat.format(date);
    }
}


来源:https://stackoverflow.com/questions/2057351/how-do-i-get-the-last-modification-time-of-a-java-resource

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!