participate


Java Programming [Archive] - Win32/NT JNI Solution for File Creation Date
<<   Back to Forum  |   Give us Feedback
This topic has 3 replies on 1 page.
mzaleski-ford
Posts:5
Registered: 12/17/02
Win32/NT JNI Solution for File Creation Date   
Jun 10, 2003 10:16 AM

 
I searched the forums and found that noone else had posted a solution for getting the file creation date on Win32. So I rolled up my sleeves, read a JNI book and what follows is a solution that worked for me. I need to enhance it in the future to handle other bits of information that Win32 provides at the file system level but, being a minimalist, this code shows that it is doable and it is fairly easy to get at the info with JNI.

To compile the C source with Microsoft C Compiler, use a line similar to the following (change the include paths to match the location of your jdk includes):
cl -Ic:\jdk1.4\include -Ic:\jdk1.4\include\win32 -MD -LD Win32FileAttributes.c -FeWin32FileAttributes.dll

Put the output DLL on the Windows PATH. My experimenting with the Sun JVM on NT is that the java.library.path environment variable includes both the ALL_USERS PATH and the USER PATH variables munged together.

NOTE: There are 2 spots in the C file with comments indicating that I should throw an exception. I didn't get around to coding them and they should be sufficiently rare. The side effect even without throwing an exception is that the result is zero (0) which matches the contract of java.io.File.lastModified() failure mode. So I'm not too concerned.


Win32FileAttributes.java
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.File;
 
public final class Win32FileAttributes {
    public static native long getCreationDate(String path);
 
    public static native long getAccessDate(String path);
 
    private Win32FileAttributes() {
    }
 
    public static void main(String[] args) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yy HH:mm:ss.SSS");
        File file = new File("c:\\xml.zip");
        long creationDateTime = Win32FileAttributes.getCreationDate(file.getPath());
        long accessDateTime = Win32FileAttributes.getAccessDate(file.getPath());
        System.out.println(file.getPath() + " created: " + dateFormat.format(new Date(creationDateTime)));
        System.out.println(file.getPath() + " last accessed: " + dateFormat.format(new Date(accessDateTime)));
    }
    static {
        System.loadLibrary("Win32FileAttributes");
    }
}
 



Win32FileAttributes.h
#include <jni.h>
/* Header for class Win32FileAttributes */
 
#ifndef _Included_Win32FileAttributes
#define _Included_Win32FileAttributes
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Win32FileAttributes
 * Method:    getCreationDate
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_Win32FileAttributes_getCreationDate
  (JNIEnv *, jclass, jstring);
 
/*
 * Class:     Win32FileAttributes
 * Method:    getAccessDate
 * Signature: (Ljava/lang/String;)J
 */
JNIEXPORT jlong JNICALL Java_Win32FileAttributes_getAccessDate
  (JNIEnv *, jclass, jstring);
 
#ifdef __cplusplus
}
#endif
#endif
 


Win32FileAttributes.c
#include <jni.h>
#include <stdio.h>
#include <windows.h>
#include "Win32FileAttributes.h"
 
static ULARGE_INTEGER G_ULI_1970;
 
BOOL ConvertDateTimeToMillisecondsSince1970(const FILETIME *lpDateTime, jlong *lqwMillis)
{
    ULARGE_INTEGER uliTime;
    BOOL bResult;
 
    /* Determine the equivalent FILETIME for Jan 1, 1970 */
    if (G_ULI_1970.QuadPart == 0) {
        SYSTEMTIME stSystemTime1970;
        FILETIME stFileTime1970;
 
        stSystemTime1970.wYear = 1970;
        stSystemTime1970.wMonth = 1;
        stSystemTime1970.wDayOfWeek = 0;
        stSystemTime1970.wDay = 1;
        stSystemTime1970.wHour = 0;
        stSystemTime1970.wMinute = 0;
        stSystemTime1970.wSecond = 0;
        stSystemTime1970.wMilliseconds = 0;
 
        bResult = SystemTimeToFileTime(&stSystemTime1970, &stFileTime1970);
        if (bResult == 0) {
            /* Throw exception here */
            return FALSE;
        }
        G_ULI_1970.LowPart = stFileTime1970.dwLowDateTime;
        G_ULI_1970.HighPart = stFileTime1970.dwHighDateTime;
    }
 
    uliTime.LowPart = lpDateTime->dwLowDateTime;
    uliTime.HighPart = lpDateTime->dwHighDateTime;
    /* Subtract off 1970 from our FILETIME */
    uliTime.QuadPart -= G_ULI_1970.QuadPart;
    /* uliTime is in 100 nanosecond ticks since 1970.  We need it in millisecond ticks since 1970 */
    uliTime.QuadPart /= 10000;
    *lqwMillis = uliTime.QuadPart;
    return TRUE;
 
}
 
JNIEXPORT jlong JNICALL
    Java_Win32FileAttributes_getCreationDate(JNIEnv *env, jclass cls, jstring jPath)
{
    const jbyte *szPath;
    jlong qwMillisSince1970;
    HANDLE hFile;
    WIN32_FIND_DATA stFileFindData;
    BOOL bResult;
 
    qwMillisSince1970 = 0;
 
 
    szPath = (*env)->GetStringUTFChars(env, jPath, NULL);
    if (szPath == NULL) {
        return qwMillisSince1970;  /* OutOfMemoryError already thrown */
    }
    hFile = FindFirstFile(szPath, &stFileFindData);
    (*env)->ReleaseStringUTFChars(env, jPath, szPath);
    if (hFile == INVALID_HANDLE_VALUE) {
        return qwMillisSince1970;
    }
    if (stFileFindData.ftCreationTime.dwLowDateTime == 0 && stFileFindData.ftCreationTime.dwHighDateTime == 0) {
        FindClose(hFile);
        return qwMillisSince1970;
    }
 
    bResult = ConvertDateTimeToMillisecondsSince1970(&stFileFindData.ftCreationTime, &qwMillisSince1970);
    if (bResult == 0) {
        /* Throw exception here */
    }
 
    FindClose(hFile);
    return qwMillisSince1970;
}
 
JNIEXPORT jlong JNICALL
    Java_Win32FileAttributes_getAccessDate(JNIEnv *env, jclass cls, jstring jPath)
{
    const jbyte *szPath;
    jlong qwMillisSince1970;
    HANDLE hFile;
    WIN32_FIND_DATA stFileFindData;
    BOOL bResult;
 
    qwMillisSince1970 = 0;
 
 
    szPath = (*env)->GetStringUTFChars(env, jPath, NULL);
    if (szPath == NULL) {
        return qwMillisSince1970;  /* OutOfMemoryError already thrown */
    }
    hFile = FindFirstFile(szPath, &stFileFindData);
    (*env)->ReleaseStringUTFChars(env, jPath, szPath);
    if (hFile == INVALID_HANDLE_VALUE) {
        return qwMillisSince1970;
    }
    if (stFileFindData.ftLastAccessTime.dwLowDateTime == 0 && stFileFindData.ftLastAccessTime.dwHighDateTime == 0) {
        FindClose(hFile);
        return qwMillisSince1970;
    }
 
    bResult = ConvertDateTimeToMillisecondsSince1970(&stFileFindData.ftLastAccessTime, &qwMillisSince1970);
    if (bResult == 0) {
        /* Throw exception here */
    }
 
    FindClose(hFile);
    return qwMillisSince1970;
}
 
 
mzaleski-ford
Posts:5
Registered: 12/17/02
Re: Win32/NT JNI Solution for File Creation Date   
Jun 10, 2003 10:22 AM (reply 1 of 3)  (In reply to original post )

 
Forgot to mention: lastAccessDate alters the last access date attribute of the file. So you will get the last access date you expect the first time to call lastAccessDate(). However the next call will give you the date/time of the last call to lastAccessDate(). It appears to be a "feature" of the Win32 file system calls. I verified this on WinXP by right-clicking a file in a file browser and choosing "Properties...". The next time I open the "Properties" for that file, the Last Access Date is the last time I opened the "Properties" dialog.
 
brainpinch
Posts:25
Registered: 8/28/03
Re: Win32/NT JNI Solution for File Creation Date   
Aug 28, 2003 7:01 AM (reply 2 of 3)  (In reply to #1 )

 
can you give me the dll file?
i have no CPP installed on my PC.
Restricted my account on that software..

thanks...
 
emartinez5
Posts:1
Registered: 7/1/04
Re: Win32/NT JNI Solution for File Creation Date   
Jul 1, 2004 6:32 AM (reply 3 of 3)  (In reply to original post )

 
Hi!
Can you please also send me the dll? I don't have C either.

Thanks!
emartinez
 
This topic has 3 replies on 1 page.
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 56
  • Guests : 138

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums