如何用Java发现文件的创build时间?
有没有一种简单的方法来发现一个文件的Java创build时间? File类只有一个获取“上次修改”时间的方法。 根据我在Google上发现的一些资源,File类没有提供getCreationTime()方法,因为并不是所有的文件系统都支持创build时间。
唯一的工作解决scheme,我发现了炮弹命令行和执行“dir”命令,看起来像输出文件的创build时间。 我想这个工程,我只需要支持Windows,但似乎很容易出错。
有没有第三方库提供我需要的信息?
更新:最后,我不认为这是值得我购买第三方库,但他们的API似乎很不错,所以这可能是任何人有这个问题的一个不错的select。
随着Java 7的发布,有一个内置的方法来做到这一点:
Path path = Paths.get("path/to/file"); BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class); FileTime creationTime = attributes.creationTime();
需要注意的是,并不是所有的操作系统都提供这些信息。 我相信在这些情况下,这将返回最后修改时间的mtime。
Windows确实提供了创build时间。
我前几天写了一个小testing课,希望能帮助你:
// 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 的文件时间(创build时间、最后修改时间、最后访问时间)"); 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 (" 创build时间:" + 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 失败"); } } } }
我一直在研究这个,但是我需要一些可以在Windows / * nix平台上运行的东西。
一个SOpost包含一些到Posix JNI实现的链接。
- JNA-POSIX
- 用于Java的POSIX
特别是,JNA-POSIX实现了获取 Windows ,BSD,Solaris,Linux和OSX实现文件统计的方法 。
总之它看起来很有希望,所以我很快就会在自己的项目上尝试一下。
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 */
javaxt-core库包含一个File类,可用于检索文件属性,包括创build时间。 例:
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及更高版本。
我喜欢jGuru的答案,列出了使用JNI来获得答案的选项。 这可能比脱壳更快,您可能会遇到其他情况,例如需要专门针对Windows执行的情况。
另外,如果你需要移植到不同的平台上,那么你也可以移植你的库,只需要返回-1就可以在* ix上得到这个问题的答案。
这是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()); }