如何获取 Java 资源的最后修改时间?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2057351/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 19:10:22  来源:igfitidea点击:

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

javaresourceslast-modified

提问by Aaron Digulla

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.

有人可以告诉我一种获取Java资源最后修改时间的可靠方法吗?资源可以是文件或 JAR 中的条目。

回答by jarnbjo

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

如果您使用“资源”表示可以通过 Class#getResource 或 ClassLoader#getResource 访问的内容,则可以通过 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".

请注意,如果最后修改时间未知,则 getLastModified() 返回 0,不幸的是,这与读取“1970 年 1 月 1 日,0:00 UTC”的真实时间戳无法区分。

回答by jt.

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

Apache Commons VFS提供了一种与来自不同来源的文件交互的通用方式。 FileObject.getContent()返回一个 FileContent 对象,该对象具有用于检索上次修改时间的方法

Here is a modified example from the VFS website:

这是来自VFS 网站的修改示例:

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());
}

回答by cornz

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().

问题url.openConnection().getLastModified()在于getLastModified()在 FileURLConnection 上为该文件创建了一个 InputStream。所以你必须urlConnection.getInputStream().close()在获得最后修改日期后打电话。相反,JarURLConnection 在调用 getInputStream() 时创建输入流。

回答by Mostowski Collapse

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().

我目前正在使用以下解决方案。该解决方案与其初始步骤中的大多数其他解决方案相同,即先使用 getResource(),然后再使用 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.

上面的代码适用于 android 和非 android,如果在存档中找到资源,它返回 ZIP 中条目的最后修改日期,否则返回从连接中获取的内容。

Bye

再见

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

PS:代码还需要刷一下,有一些边框情况getJarEntry()为null。

回答by BullyWiiPlaza

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

这是我用于获取JAR文件或编译类的最后修改时间的代码(使用 时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);
    }
}