有没有一种简单的方法可以用Java发现文件的创建时间? File类只有一个获取“上次修改”时间的方法。根据我在Google上找到的一些资源,File类不提供getCreationTime()方法,因为并非所有文件系统都支持创建时的想法。
唯一可行的解决方案是我发现involes会弹出命令行并执行“dir”命令,看起来它会输出文件的创建时间。我想这很有用,我只需要支持Windows,但这对我来说似乎很容易出错。
是否有任何第三方图书馆提供我需要的信息?
更新最后,我认为购买第三方库并不值得我购买第三方库,但他们的API看起来确实不错,所以对于其他人来说这可能是一个不错的选择。有这个问题。
答案 0 :(得分:21)
随着Java 7的发布,有一种内置的方法可以做到这一点:
Path path = Paths.get("path/to/file");
BasicFileAttributes attributes = Files.readAttributes(path, BasicFileAttributes.class);
FileTime creationTime = attributes.creationTime();
请务必注意,并非所有操作系统都提供此信息。我相信在这些情况下,它会返回mtime,这是最后修改的时间。
Windows确实提供了创建时间。
答案 1 :(得分:8)
我几天前写过一个小型测试课,希望它可以帮到你:
// 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 失败");
}
}
}
}
答案 2 :(得分:2)
我自己一直在研究这个问题,但我需要能够在Windows / * nix平台上运行的东西。
一个SO帖子包含一些指向Posix JNI implementations的链接。
特别是,JNA-POSIX实现methods for getting file stats实现Windows,BSD,Solaris,Linux和OSX。
总而言之,它看起来非常有前景,所以我很快就会在我自己的项目上尝试它。
答案 3 :(得分: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
*/
答案 4 :(得分:2)
javaxt-core库包含一个File类,可用于检索文件属性,包括创建时间。例如:
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及更高版本。
答案 5 :(得分:1)
我喜欢jGuru上的答案,其中列出了使用JNI获取答案的选项。这可能比炮轰更快,你可能会遇到其他需要专门为windows实现的情况。
此外,如果您需要移植到不同的平台,那么您也可以移植您的库,只需将它返回-1以获取* ix上此问题的答案。
答案 6 :(得分:0)
这是使用BasicFileAttributes
class:
Java
中的基本示例
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());
}