15

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

4

5 回答 5

20

如果您使用“资源”表示可以通过 Class#getResource 或 ClassLoader#getResource 访问的内容,则可以通过 URLConnection 获取上次修改的时间戳:

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

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

于 2010-01-13T14:44:32.563 回答
6

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

于 2010-06-10T13:36:03.000 回答
5

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

这是来自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());
}
于 2010-01-13T14:49:32.103 回答
2

我目前正在使用以下解决方案。该解决方案与大多数其他解决方案的初始步骤相同,即一些 getResource(),然后是 openConnection()。

但是当我有连接时,我正在使用以下代码:

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

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

再见

PS:代码还是需要刷的,有些边界情况getJarEntry()为null。

于 2014-10-26T18:36:07.083 回答
1

这是我获取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);
    }
}
于 2017-01-16T00:41:10.137 回答