A DESCRIPTION OF THE FIX :
Bug Description : java.io.File can provide access to created and last-access times.
Subset of Releases affected : 1.5.0, Mustang b41.
Platforms affected : Windows, Solaris, Linux
Test case : See Test case section.
Diff baseline : Mustang b41
Diff :
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\share\classes\java\io\File.java 2005-08-04 21:55:42.000000000 +0200
+++ ..\src\share\classes\java\io\File.java 2005-08-09 02:46:30.256833600 +0200
@@ -3,6 +3,8 @@
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
package java.io;
@@ -798,6 +800,54 @@
The fix and test case are too large to include here. Refer to the attached file
508675.txt.
A DESCRIPTION OF THE FIX :
Bug Description : java.io.File can provide access to created and last-access times.
Subset of Releases affected : 1.5.0, Mustang b41.
Platforms affected : Windows, Solaris, Linux
Test case : See Test case section.
Diff baseline : Mustang b41
Diff :
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\share\classes\java\io\File.java 2005-08-04 21:55:42.000000000 +0200
+++ ..\src\share\classes\java\io\File.java 2005-08-09 02:46:30.256833600 +0200
@@ -3,6 +3,8 @@
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
package java.io;
@@ -798,6 +800,54 @@
/**
* Returns the time that the file denoted by this abstract pathname was
+ * created.
+ *
+ * @return A <code>long</code> value representing the time the file was
+ * created, measured in milliseconds since the epoch
+ * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
+ * file does not exist or if an I/O error occurs
+ *
+ * @throws SecurityException
+ * If a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
+ * method denies read access to the file
+ *
+ * @since 6.0
+ */
+ public long created() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkRead(path);
+ }
+ return fs.getCreatedTime(this);
+ }
+
+ /**
+ * Returns the time that the file denoted by this abstract pathname was
+ * last accessed.
+ *
+ * @return A <code>long</code> value representing the time the file was
+ * last accessed, measured in milliseconds since the epoch
+ * (00:00:00 GMT, January 1, 1970), or <code>0L</code> if the
+ * file does not exist or if an I/O error occurs
+ *
+ * @throws SecurityException
+ * If a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkRead(java.lang.String)}</code>
+ * method denies read access to the file
+ *
+ * @since 6.0
+ */
+ public long lastAccessed() {
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkRead(path);
+ }
+ return fs.getLastAccessedTime(this);
+ }
+
+ /**
+ * Returns the time that the file denoted by this abstract pathname was
* last modified.
*
* @return A <code>long</code> value representing the time the file was
@@ -1216,6 +1266,78 @@
}
/**
+ * Sets the created time of the file or directory named by this
+ * abstract pathname.
+ *
+ * <p> All platforms support file-creation times to the nearest second,
+ * but some provide more precision. The argument will be truncated to fit
+ * the supported precision. If the operation succeeds and no intervening
+ * operations on the file take place, then the next invocation of the
+ * <code>{@link #created}</code> method will return the (possibly
+ * truncated) <code>time</code> argument that was passed to this method.
+ * <p>
+ * <b>Note:</b> this method is not available on UNIX systems.
+ *
+ * @param time The new created time, measured in milliseconds since
+ * the epoch (00:00:00 GMT, January 1, 1970)
+ *
+ * @return <code>true</code> if and only if the operation succeeded;
+ * <code>false</code> otherwise
+ *
+ * @throws IllegalArgumentException If the argument is negative
+ *
+ * @throws SecurityException
+ * If a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
+ * method denies write access to the named file
+ *
+ * @since 6.0
+ */
+ public boolean setCreated(long time) {
+ if (time < 0) throw new IllegalArgumentException("Negative time");
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkWrite(path);
+ }
+ return fs.setCreatedTime(this, time);
+ }
+
+ /**
+ * Sets the last-accessed time of the file or directory named by this
+ * abstract pathname.
+ *
+ * <p> All platforms support file-access times to the nearest second,
+ * but some provide more precision. The argument will be truncated to fit
+ * the supported precision. If the operation succeeds and no intervening
+ * operations on the file take place, then the next invocation of the
+ * <code>{@link #lastAccessed}</code> method will return the (possibly
+ * truncated) <code>time</code> argument that was passed to this method.
+ *
+ * @param time The new last-accessed time, measured in milliseconds since
+ * the epoch (00:00:00 GMT, January 1, 1970)
+ *
+ * @return <code>true</code> if and only if the operation succeeded;
+ * <code>false</code> otherwise
+ *
+ * @throws IllegalArgumentException If the argument is negative
+ *
+ * @throws SecurityException
+ * If a security manager exists and its <code>{@link
+ * java.lang.SecurityManager#checkWrite(java.lang.String)}</code>
+ * method denies write access to the named file
+ *
+ * @since 6.0
+ */
+ public boolean setLastAccessed(long time) {
+ if (time < 0) throw new IllegalArgumentException("Negative time");
+ SecurityManager security = System.getSecurityManager();
+ if (security != null) {
+ security.checkWrite(path);
+ }
+ return fs.setLastAccessedTime(this, time);
+ }
+
+ /**
* Sets the last-modified time of the file or directory named by this
* abstract pathname.
*
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\share\classes\java\io\FileSystem.java 2005-08-04 21:55:42.000000000 +0200
+++ ..\src\share\classes\java\io\FileSystem.java 2005-08-09 02:38:14.914566400 +0200
@@ -3,6 +3,8 @@
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
package java.io;
@@ -111,6 +113,20 @@
/**
* Return the time at which the file or directory denoted by the given
+ * abstract pathname was created, or zero if it does not exist or
+ * some other I/O error occurs.
+ */
+ public abstract long getCreatedTime(File f);
+
+ /**
+ * Return the time at which the file or directory denoted by the given
+ * abstract pathname was last accessed, or zero if it does not exist or
+ * some other I/O error occurs.
+ */
+ public abstract long getLastAccessedTime(File f);
+
+ /**
+ * Return the time at which the file or directory denoted by the given
* abstract pathname was last modified, or zero if it does not exist or
* some other I/O error occurs.
*/
@@ -169,6 +185,20 @@
public abstract boolean rename(File f1, File f2);
/**
+ * Set the created time of the file or directory denoted by the
+ * given abstract pathname, returning <code>true</code> if and only if the
+ * operation succeeds.
+ */
+ public abstract boolean setCreatedTime(File f, long time);
+
+ /**
+ * Set the last-accessed time of the file or directory denoted by the
+ * given abstract pathname, returning <code>true</code> if and only if the
+ * operation succeeds.
+ */
+ public abstract boolean setLastAccessedTime(File f, long time);
+
+ /**
* Set the last-modified time of the file or directory denoted by the
* given abstract pathname, returning <code>true</code> if and only if the
* operation succeeds.
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\windows\classes\java\io\Win32FileSystem.java 2005-08-04 21:56:52.000000000 +0200
+++ ..\src\windows\classes\java\io\Win32FileSystem.java 2005-08-09 02:36:24.255446400 +0200
@@ -3,6 +3,8 @@
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
package java.io;
@@ -485,6 +487,9 @@
public native int getBooleanAttributes(File f);
public native boolean checkAccess(File f, boolean write);
+
+ public native long getCreatedTime(File f);
+ public native long getLastAccessedTime(File f);
public native long getLastModifiedTime(File f);
public native long getLength(File f);
@@ -518,6 +523,9 @@
return rename0(f1, f2);
}
protected native boolean rename0(File f1, File f2);
+
+ public native boolean setCreatedTime(File f, long time);
+ public native boolean setLastAccessedTime(File f, long time);
public native boolean setLastModifiedTime(File f, long time);
public native boolean setReadOnly(File f);
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\windows\classes\java\io\WinNTFileSystem.java 2005-08-04 21:56:52.000000000 +0200
+++ ..\src\windows\classes\java\io\WinNTFileSystem.java 2005-08-09 02:36:21.571587200 +0200
@@ -1,10 +1,10 @@
/*
+ * @(#)WinNTFileSystem.java 1.9 04/03/20
+ *
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
- */
-
-/*
- * @(#)WinNTFileSystem.java 1.9 04/03/20
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
package java.io;
@@ -28,6 +28,8 @@
public native int getBooleanAttributes(File f);
public native boolean checkAccess(File f, boolean write);
+ public native long getCreatedTime(File f);
+ public native long getLastAccessedTime(File f);
public native long getLastModifiedTime(File f);
public native long getLength(File f);
@@ -41,6 +43,8 @@
public native String[] list(File f);
public native boolean createDirectory(File f);
protected native boolean rename0(File f1, File f2);
+ public native boolean setCreatedTime(File f, long time);
+ public native boolean setLastAccessedTime(File f, long time);
public native boolean setLastModifiedTime(File f, long time);
public native boolean setReadOnly(File f);
protected native String getDriveDirectory(int drive);
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\solaris\classes\java\io\UnixFileSystem.java 2005-08-04 21:56:46.000000000 +0200
+++ ..\src\solaris\classes\java\io\UnixFileSystem.java 2005-08-09 02:37:57.219121600 +0200
@@ -3,6 +3,8 @@
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
package java.io;
@@ -232,6 +234,9 @@
}
public native boolean checkAccess(File f, boolean write);
+
+ public native long getCreatedTime(File f);
+ public native long getLastAccessedTime(File f);
public native long getLastModifiedTime(File f);
public native long getLength(File f);
@@ -265,6 +270,12 @@
return rename0(f1, f2);
}
private native boolean rename0(File f1, File f2);
+
+ //public native boolean setCreatedTime(File f, long time); // TODO by UNIX experts
+ public boolean setCreatedTime(File f, long time) {
+ return false; // Not available for UNIX systems ? (Ulf Zibis)
+ }
+ public native boolean setLastAccessedTime(File f, long time);
public native boolean setLastModifiedTime(File f, long time);
public native boolean setReadOnly(File f);
--- G:\jdk6.0 ea ausgepackt\src-b41\j2se\src\windows\native\java\io\Win32FileSystem_md.c 2005-08-02 20:28:36.000000000 +0200
+++ ..\src\windows\native\java\io\Win32FileSystem_md.c 2005-08-09 02:51:55.594646400 +0200
@@ -3,6 +3,8 @@
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ *
+ * Contributors: Ulf Zibis, Germany, mailto:###@###.###
*/
#include <assert.h>
@@ -134,24 +136,62 @@
}
+jlong
+javaTime(FILETIME t)
+{
+ LARGE_INTEGER time;
+ time.LowPart = (DWORD) t.dwLowDateTime;
+ time.HighPart = (LONG) t.dwHighDateTime;
+ return (jlong) time.QuadPart / 10000 - 11644473600000;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_Win32FileSystem_getCreatedTime(JNIEnv *env, jobject this,
+ jobject file)
+{
+ jlong rv = 0;
+ WITH_NATIVE_PATH(env, file, ids.path, path) {
+ /* Win95, Win98, WinME */
+ WIN32_FIND_DATA fd;
+ HANDLE h = FindFirstFile(path, &fd);
+ if (h != INVALID_HANDLE_VALUE) {
+ FindClose(h);
+ rv = javaTime(fd.ftCreationTime);
+ }
+ } END_NATIVE_PATH(env, path);
+ return rv;
+}
+
+JNIEXPORT jlong JNICALL
+Java_java_io_Win32FileSystem_getLastAccessedTime(JNIEnv *env, jobject this,
+ jobject file)
+{
+ jlong rv = 0;
+ WITH_NATIVE_PATH(env, file, ids.path, path) {
+ /* Win95, Win98, WinME */
+ WIN32_FIND_DATA fd;
+ HANDLE h = FindFirstFile(path, &fd);
+ if (h != INVALID_HANDLE_VALUE) {
+ FindClose(h);
+ rv = javaTime(fd.ftLastAccessTime);
+ }
+ } END_NATIVE_PATH(env, path);
+ return rv;
+}
+
JNIEXPORT jlong JNICALL
Java_java_io_Win32FileSystem_getLastModifiedTime(JNIEnv *env, jobject this,
jobject file)
{
jlong rv = 0;
WITH_NATIVE_PATH(env, file, ids.path, path) {
- /* Win95, Win98, WinME */
- WIN32_FIND_DATA fd;
- jlong temp = 0;
- LARGE_INTEGER modTime;
- HANDLE h = FindFirstFile(path, &fd);
- if (h != INVALID_HANDLE_VALUE) {
- FindClose(h);
- modTime.LowPart = (DWORD) fd.ftLastWriteTime.dwLowDateTime;
- modTime.HighPart = (LONG) fd.ftLastWriteTime.dwHighDateTime;
- rv = modTime.QuadPart / 10000;
- rv -= 11644473600000;
- }
+ /* Win95, Win98, WinME */
+ WIN32_FIND_DATA fd;
+ HANDLE h = FindFirstFile(path, &fd);
+ if (h != INVALID_HANDLE_VALUE) {
+ FindClose(h);
+ rv = javaTime(fd.ftLastWriteTime);
+ }
} END_NATIVE_PATH(env, path);
return rv;
}
@@ -328,6 +368,61 @@
}
+HANDLE
+createSetFileTimeHandle()
+{
+ return CreateFileW(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
+}
+
+FILETIME
+j2FileTime(jlong time)
+{
+ FILETIME t;
+ ((LARGE_INTEGER)time).QuadPart = (time + 11644473600000L) * 10000L;
+ t.dwLowDateTime = (DWORD)((LARGE_INTEGER)time).LowPart;
+ t.dwHighDateTime = (DWORD)((LARGE_INTEGER)time).HighPart;
+ return t;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_Win32FileSystem_setCreatedTime(JNIEnv *env, jobject this,
+ jobject file, jlong time)
+{
+ jboolean rv = JNI_FALSE;
+
+ WITH_NATIVE_PATH(env, file, ids.path, path) {
+ HANDLE h = createSetFileTimeHandle();
+ if (h != INVALID_HANDLE_VALUE) {
+ FILETIME t = j2FileTime(time);
+ if (SetFileTime(h, &t, NULL, NULL))
+ rv = JNI_TRUE;
+ CloseHandle(h);
+ }
+ } END_NATIVE_PATH(env, path);
+
+ return rv;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_java_io_Win32FileSystem_setLastAccessedTime(JNIEnv *env, jobject this,
+ jobject file, jlong time)
+{
+ jboolean rv = JNI_FALSE;
+
+ WITH_NATIVE_PATH(env, file, ids.path, path) {
+ HANDLE h = createSetFileTimeHandle();
+ if (h != INVALID_HANDLE_VALUE) {
+ FILETIME t = j2FileTime(time);
+ if (SetFileTime(h, NULL, &t, NULL))
+ rv = JNI_TRUE;
+ CloseHandle(h);
+ }
+ } END_NATIVE_PATH(env, path);
+
+ return rv;
+}
+
JNIEXPORT jboolean JNICALL
Java_java_io_Win32FileSystem_setLastModifiedTime(JNIEnv *env, jobject this,
jobject file, jlong time)
@@ -335,20 +430,13 @@
jboolean rv = JNI_FALSE;
WITH_NATIVE_PATH(env, file, ids.path, path) {
- HANDLE h;
- h = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
- if (h != INVALID_HANDLE_VALUE) {
- LARGE_INTEGER modTime;
- FILETIME t;
- modTime.QuadPart = (time + 11644473600000L) * 10000L;
- t.dwLowDateTime = (DWORD)modTime.LowPart;
- t.dwHighDateTime = (DWORD)modTime.HighPart;
- if (SetFileTime(h, NULL, NULL, &t)) {
- rv = JNI_TRUE;
- }
-