代码之家  ›  专栏  ›  技术社区  ›  Tim Frey

如何用Java发现文件的创建时间?

  •  23
  • Tim Frey  · 技术社区  · 18 年前

    有没有一种简单的方法可以用Java发现文件的创建时间?文件类只有一个方法来获取“上次修改”时间。根据我在Google上找到的一些资源,File类没有提供getCreationTime()方法,因为不是所有的文件系统都支持创建时间的概念。

    我找到的唯一工作解决方案是执行命令行并执行“dir”命令,看起来它输出文件的创建时间。我想这是可行的,我只需要支持Windows,但对我来说似乎很容易出错。

    有没有第三方图书馆提供我需要的信息?

    更新: 最后,我认为我不值得购买第三方库,但是他们的API看起来非常不错,所以对于其他有这个问题的人来说,这可能是个不错的选择。

    7 回复  |  直到 18 年前
        1
  •  21
  •   ajon    13 年前

    随着Java7的发布,有一种内置的方法可以做到这一点:

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

    需要注意的是,并非所有操作系统都提供此信息。我相信在这些情况下,这会返回mtime,这是最后一次修改的时间。

    Windows确实提供了创建时间。

        2
  •  8
  •   LiuYan 刘研    13 年前

    几天前我写了一个小测试班,希望它能帮助你:

    // 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 失败");
                }
            }
        }
    }
    
        3
  •  2
  •   Community Mohan Dere    9 年前

    我一直在调查这个问题,但我需要一些可以在Windows/*nix平台上运行的东西。

    一个这样的帖子包括一些链接到 Posix JNI implementations .

    特别是,JNA-POSIX实现 methods for getting file stats 实现了 Windows ,BSD,Solaris,Linux和OSX。

    总而言之,它看起来很有前途,所以我很快就会在我自己的项目上尝试。

        4
  •  2
  •   leonbloy    14 年前
    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
    
    */
    
        5
  •  2
  •   Peter    13 年前

    这个 javaxt-core 库包含一个文件类,可用于检索文件属性,包括创建时间。例子:

    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());
    

    适用于Java 1.5及更高版本。

        6
  •  1
  •   Joseph Gordon    18 年前

    我喜欢这个答案 jGuru 列出了使用 JNI 得到答案。这可能被证明比炮击更快,并且您可能会遇到其他情况,例如需要专门为windows实现的情况。

    另外,如果您需要移植到不同的平台,那么您也可以移植您的库,并让它返回-1,以便在*ix上回答这个问题。

        7
  •  0
  •   Jorgesys    10 年前

    这是中的一个基本示例 Java ,使用 BasicFileAttributes 班级:

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