24

Is there an easy way to discover a File's creation time with Java? The File class only has a method to get the "last modified" time. According to some resources I found on Google, the File class doesn't provide a getCreationTime() method because not all file systems support the idea of a creation time.

The only working solution I found involes shelling out the the command line and executing the "dir" command, which looks like it outputs the file's creation time. I guess this works, I only need to support Windows, but it seems very error prone to me.

Are there any third party libraries that provide the info I need?

Update: In the end, I don't think it's worth it for me to buy the third party library, but their API does seem pretty good so it's probably a good choice for anyone else that has this problem.

Tim Frey
  • 9,901
  • 9
  • 44
  • 60
  • I checked the [Apache Commons VFS](http://commons.apache.org/vfs/), in which a virtual file system can export a rich set of Capability. But unfortunately, there is no CREATION_TIME capability defined, though. – Lenik Jan 10 '11 at 08:31
  • AFAIK, NIO-2 solvers this problem but is not released yet (should be in 7'th version). See for example http://java.sun.com/developer/technicalArticles/javase/nio/ and http://today.java.net/article/2009/10/14/sweeping-file-system-nio-2 – Petr Gladkikh Mar 07 '11 at 13:04

7 Answers7

21

With the release of Java 7 there is a built-in way to do this:

Path path = Paths.get("path/to/file");
BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class);
FileTime creationTime = attributes.creationTime();

It is important to note that not all operating systems provide this information. I believe in those instances this returns the mtime which is the last modified time.

Windows does provide creation time.

ajon
  • 7,868
  • 11
  • 48
  • 86
8

I've wrote a small test class some days ago, wish it can help you:

// Get/Set windows file CreationTime/LastWriteTime/LastAccessTime
// Test with jna-3.2.7
// [http://maclife.net/wiki/index.php?title=Java_get_and_set_windows_system_file_creation_time_via_JNA_(Java_Native_Access)][1]

import java.io.*;
import java.nio.*;
import java.util.Date;

// Java Native Access library: jna.dev.java.net
import com.sun.jna.*;
import com.sun.jna.ptr.*;
import com.sun.jna.win32.*;
import com.sun.jna.platform.win32.*;

public class WindowsFileTime
{
    public static final int GENERIC_READ = 0x80000000;
    //public static final int GENERIC_WRITE = 0x40000000;   // defined in com.sun.jna.platform.win32.WinNT
    public static final int GENERIC_EXECUTE = 0x20000000;
    public static final int GENERIC_ALL = 0x10000000;

    // defined in com.sun.jna.platform.win32.WinNT
    //public static final int CREATE_NEW = 1;
    //public static final int CREATE_ALWAYS = 2;
    //public static final int OPEN_EXISTING = 3;
    //public static final int OPEN_ALWAYS = 4;
    //public static final int TRUNCATE_EXISTING = 5;

    public interface MoreKernel32 extends Kernel32
    {
        static final MoreKernel32 instance = (MoreKernel32)Native.loadLibrary ("kernel32", MoreKernel32.class, W32APIOptions.DEFAULT_OPTIONS);
        boolean GetFileTime (WinNT.HANDLE hFile, WinBase.FILETIME lpCreationTime, WinBase.FILETIME lpLastAccessTime, WinBase.FILETIME lpLastWriteTime);
        boolean SetFileTime (WinNT.HANDLE hFile, final WinBase.FILETIME lpCreationTime, final WinBase.FILETIME lpLastAccessTime, final WinBase.FILETIME lpLastWriteTime);
    }

    static MoreKernel32 win32 = MoreKernel32.instance;
    //static Kernel32 _win32 = (Kernel32)win32;

    static WinBase.FILETIME _creationTime = new WinBase.FILETIME ();
    static WinBase.FILETIME _lastWriteTime = new WinBase.FILETIME ();
    static WinBase.FILETIME _lastAccessTime = new WinBase.FILETIME ();

    static boolean GetFileTime (String sFileName, Date creationTime, Date lastWriteTime, Date lastAccessTime)
    {
        WinNT.HANDLE hFile = OpenFile (sFileName, GENERIC_READ);    // may be WinNT.GENERIC_READ in future jna version.
        if (hFile == WinBase.INVALID_HANDLE_VALUE) return false;

        boolean rc = win32.GetFileTime (hFile, _creationTime, _lastAccessTime, _lastWriteTime);
        if (rc)
        {
            if (creationTime != null) creationTime.setTime (_creationTime.toLong());
            if (lastAccessTime != null) lastAccessTime.setTime (_lastAccessTime.toLong());
            if (lastWriteTime != null) lastWriteTime.setTime (_lastWriteTime.toLong());
        }
        else
        {
            int iLastError = win32.GetLastError();
            System.out.print ("获取文件时间失败,错误码:" + iLastError + " " + GetWindowsSystemErrorMessage (iLastError));
        }
        win32.CloseHandle (hFile);
        return rc;
    }
    static boolean SetFileTime (String sFileName, final Date creationTime, final Date lastWriteTime, final Date lastAccessTime)
    {
        WinNT.HANDLE hFile = OpenFile (sFileName, WinNT.GENERIC_WRITE);
        if (hFile == WinBase.INVALID_HANDLE_VALUE) return false;

        ConvertDateToFILETIME (creationTime, _creationTime);
        ConvertDateToFILETIME (lastWriteTime, _lastWriteTime);
        ConvertDateToFILETIME (lastAccessTime, _lastAccessTime);

        //System.out.println ("creationTime: " + creationTime);
        //System.out.println ("lastWriteTime: " + lastWriteTime);
        //System.out.println ("lastAccessTime: " + lastAccessTime);

        //System.out.println ("_creationTime: " + _creationTime);
        //System.out.println ("_lastWriteTime: " + _lastWriteTime);
        //System.out.println ("_lastAccessTime: " + _lastAccessTime);

        boolean rc = win32.SetFileTime (hFile, creationTime==null?null:_creationTime, lastAccessTime==null?null:_lastAccessTime, lastWriteTime==null?null:_lastWriteTime);
        if (! rc)
        {
            int iLastError = win32.GetLastError();
            System.out.print ("设置文件时间失败,错误码:" + iLastError + " " + GetWindowsSystemErrorMessage (iLastError));
        }
        win32.CloseHandle (hFile);
        return rc;
    }
    static void ConvertDateToFILETIME (Date date, WinBase.FILETIME ft)
    {
        if (ft != null)
        {
            long iFileTime = 0;
            if (date != null)
            {
                iFileTime = WinBase.FILETIME.dateToFileTime (date);
                ft.dwHighDateTime = (int)((iFileTime >> 32) & 0xFFFFFFFFL);
                ft.dwLowDateTime = (int)(iFileTime & 0xFFFFFFFFL);
            }
            else
            {
                ft.dwHighDateTime = 0;
                ft.dwLowDateTime = 0;
            }
        }
    }

    static WinNT.HANDLE OpenFile (String sFileName, int dwDesiredAccess)
    {
        WinNT.HANDLE hFile = win32.CreateFile (
            sFileName,
            dwDesiredAccess,
            0,
            null,
            WinNT.OPEN_EXISTING,
            0,
            null
            );
        if (hFile == WinBase.INVALID_HANDLE_VALUE)
        {
            int iLastError = win32.GetLastError();
            System.out.print (" 打开文件失败,错误码:" + iLastError + " " + GetWindowsSystemErrorMessage (iLastError));
        }
        return hFile;
    }
    static String GetWindowsSystemErrorMessage (int iError)
    {
        char[] buf = new char[255];
        CharBuffer bb = CharBuffer.wrap (buf);
        //bb.clear ();
        //PointerByReference pMsgBuf = new PointerByReference ();
        int iChar = win32.FormatMessage (
                WinBase.FORMAT_MESSAGE_FROM_SYSTEM
                    //| WinBase.FORMAT_MESSAGE_IGNORE_INSERTS
                    //|WinBase.FORMAT_MESSAGE_ALLOCATE_BUFFER
                    ,
                null,
                iError,
                0x0804,
                bb, buf.length,
                //pMsgBuf, 0,
                null
            );
        //for (int i=0; i<iChar; i++)
        //{
        //  System.out.print (" ");
        //  System.out.print (String.format("%02X", buf[i]&0xFFFF));
        //}
        bb.limit (iChar);
        //System.out.print (bb);
        //System.out.print (pMsgBuf.getValue().getString(0));
        //win32.LocalFree (pMsgBuf.getValue());
        return bb.toString ();
    }

    public static void main (String[] args) throws Exception
    {
        if (args.length == 0)
        {
            System.out.println ("获取 Windows 的文件时间(创建时间、最后修改时间、最后访问时间)");
            System.out.println ("用法:");
            System.out.println ("   java -cp .;..;jna.jar;platform.jar WindowsFileTime [文件名1] [文件名2]...");
            return;
        }

        boolean rc;
        java.sql.Timestamp ct = new java.sql.Timestamp(0);
        java.sql.Timestamp wt = new java.sql.Timestamp(0);
        java.sql.Timestamp at = new java.sql.Timestamp(0);

        for (String sFileName : args)
        {
            System.out.println ("文件 " + sFileName);

            rc = GetFileTime (sFileName, ct, wt, at);
            if (rc)
            {
                System.out.println ("   创建时间:" + ct);
                System.out.println ("   修改时间:" + wt);
                System.out.println ("   访问时间:" + at);
            }
            else
            {
                //System.out.println ("GetFileTime 失败");
            }


            //wt.setTime (System.currentTimeMillis());
            wt = java.sql.Timestamp.valueOf("2010-07-23 00:00:00");
            rc = SetFileTime (sFileName, null, wt, null);
            if (rc)
            {
                System.out.println ("SetFileTime (最后修改时间) 成功");
            }
            else
            {
                //System.out.println ("SetFileTime 失败");
            }
        }
    }
}
LiuYan 刘研
  • 1,614
  • 1
  • 16
  • 29
2

The javaxt-core library includes a File class that can be used to retrieve file attributes, including the creation time. Example:

javaxt.io.File file = new javaxt.io.File("/temp/file.txt");
System.out.println("Created: " + file.getCreationTime());
System.out.println("Accessed: " + file.getLastAccessTime());
System.out.println("Modified: " + file.getLastModifiedTime());

Works with Java 1.5 and up.

Peter
  • 1,182
  • 2
  • 12
  • 23
2

I've been investigating this myself, but I need something that will work across Windows/*nix platforms.

One SO post includes some links to Posix JNI implementations.

In particular, JNA-POSIX implements methods for getting file stats with implementations for Windows, BSD, Solaris, Linux and OSX.

All in all it looks very promising, so I'll be trying it out on my own project very soon.

Community
  • 1
  • 1
Kothar
  • 6,579
  • 3
  • 33
  • 42
2
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;


public class CreateDateInJava {
    public static void main(String args[]) {
        try {

            // get runtime environment and execute child process
            Runtime systemShell = Runtime.getRuntime();
            BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
            System.out.println("Enter filename: ");
            String fname = (String) br1.readLine();
            Process output = systemShell.exec("cmd /c dir \"" + fname + "\" /tc");

            System.out.println(output);
            // open reader to get output from process
            BufferedReader br = new BufferedReader(new InputStreamReader(output.getInputStream()));

            String out = "";
            String line = null;

            int step = 1;
            while ((line = br.readLine()) != null) {
                if (step == 6) {
                    out = line;
                }
                step++;
            }

            // display process output
            try {
                out = out.replaceAll(" ", "");
                System.out.println("CreationDate: " + out.substring(0, 10));
                System.out.println("CreationTime: " + out.substring(10, 16) + "m");
            } catch (StringIndexOutOfBoundsException se) {
                System.out.println("File not found");
            }
        } catch (IOException ioe) {
            System.err.println(ioe);
        } catch (Throwable t) {
            t.printStackTrace();
        }
    }
}

/**
D:\Foldername\Filename.Extension

Ex:
Enter Filename :
D:\Kamal\Test.txt
CreationDate: 02/14/2011
CreationTime: 12:59Pm

*/
leonbloy
  • 73,180
  • 20
  • 142
  • 190
Kamal
  • 21
  • 1
1

I like the answer on jGuru that lists the option of using JNI to get the answer. This might prove to be faster than shelling out and you may encounter other situations such as this that need to be implemented specifically for windows.

Also, if you ever need to port to a different platform, then you can port your library as well and just have it return -1 for the answer to this question on *ix.

Joseph Gordon
  • 2,356
  • 2
  • 23
  • 27
0

This is a basic example in Java, using BasicFileAttributes class:

   Path path = Paths.get("C:\\Users\\jorgesys\\workspaceJava\\myfile.txt");
    BasicFileAttributes attr;
    try {
      attr = Files.readAttributes(path, BasicFileAttributes.class);
      System.out.println("File creation time: " + attr.creationTime());
    } catch (IOException e) {
      System.out.println("oops un error! " + e.getMessage());
    }
Jorgesys
  • 124,308
  • 23
  • 334
  • 268