如何使用Java发现文件的创建时间?
时间:2020-03-05 18:44:28 来源:igfitidea点击:
有没有一种简单的方法来用Java发现文件的创建时间? File类仅具有一种获取"上次修改"时间的方法。根据我在Google上发现的一些资源,File类没有提供getCreationTime()方法,因为并非所有文件系统都支持创建时间的想法。
我发现唯一可行的解决方案是卷入命令行并执行" dir"命令,该命令看起来像输出文件的创建时间。我想这可行,我只需要支持Windows,但是我似乎很容易出错。
是否有任何第三方图书馆提供我需要的信息?
更新:最后,我认为购买第三方库对我来说不值得,但是它们的API看起来确实不错,所以对于任何有此问题的人来说,它都是一个不错的选择。
解决方案
回答
我喜欢jGuru上的答案,其中列出了使用JNI获得答案的选项。这可能比脱壳要快,并且我们可能会遇到其他情况,例如需要专门针对Windows实施的情况。
另外,如果我们需要移植到其他平台,那么也可以移植库,并在* ix上让它返回-1来回答该问题。
回答
我一直在自己进行调查,但是我需要一些可以在Windows / * nix平台上运行的工具。
一则SO帖子中包含一些指向Posix JNI实现的链接。
- JNA-POSIX
- POSIX Java版
特别是,JNA-POSIX通过Windows,BSD,Solaris,Linux和OSX的实现来实现用于获取文件统计信息的方法。
总而言之,它看起来非常有前途,所以我将很快在自己的项目中进行尝试。
回答
我几天前写了一个小测试班,希望它能对我们有所帮助:
// 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 失败"); } } } }