Как получить время последней модификации ресурса Java?
Может кто-нибудь сказать мне надежный способ получить время последней модификации ресурса Java? Ресурс может быть файлом или записью в JAR.
5 ответов
Если вы под "ресурсом" подразумеваете что-то достижимое через Class#getResource или ClassLoader#getResource, вы можете получить последнюю измененную метку времени через URLConnection:
URL url = Test.class.getResource("/org/jdom/Attribute.class");
System.out.println(new Date(url.openConnection().getLastModified()));
Помните, что getLastModified() возвращает 0, если последнее изменение неизвестно, что, к сожалению, невозможно отличить от реальной отметки времени "1 января 1970 года, 0:00 UTC".
Проблема с url.openConnection().getLastModified()
в том, что getLastModified()
в FileURLConnection создает InputStream для этого файла. Так что вы должны позвонить urlConnection.getInputStream().close()
после получения последней измененной даты. В отличие от этого JarURLConnection создает поток ввода при вызове getInputStream().
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());
}
В настоящее время я использую следующее решение. Решение такое же, как и у большинства других решений на начальных этапах, а именно, 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 и non-android, он возвращает дату последнего изменения записи внутри ZIP, если ресурсы найдены внутри архива, в противном случае он возвращает то, что получает от соединения.
до свидания
PS: код все еще нуждается в некоторой чистке, есть некоторые граничные случаи, когда getJarEntry() имеет значение null.
Вот мой код для получения времени последней модификации вашего 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);
}
}