Как узнать время создания файла с помощью Java?

Есть ли простой способ узнать время создания файла с помощью Java? Класс File имеет только метод для получения времени «последнего изменения». Согласно некоторым ресурсам, которые я нашел в Google, класс File не предоставляет метод getCreationTime(), потому что не все файловые системы поддерживают идею времени создания.

Единственное рабочее решение, которое я нашел, включает обстрел командной строки и выполнение команды «dir», которая выглядит так, как будто выводит время создания файла. Я думаю, это работает, мне нужно только поддерживать Windows, но мне кажется, что это очень подвержено ошибкам.

Существуют ли сторонние библиотеки, предоставляющие необходимую мне информацию?

Обновление: В конце концов, я не думаю, что мне стоит покупать стороннюю библиотеку, но их API кажется довольно хорошим, поэтому, вероятно, это хороший выбор для всех, у кого есть эта проблема. .


person Outlaw Programmer    schedule 28.08.2008    source источник
comment
Я проверил VFS Apache Commons, в которой виртуальная файловая система может экспортировать широкий набор возможностей. Но, к сожалению, возможность CREATION_TIME не определена.   -  person Xiè Jìléi    schedule 10.01.2011
comment
Насколько я знаю, NIO-2 решает эту проблему, но еще не выпущен (должен быть в 7-й версии). См., например, java.sun.com/developer/technicalArticles/javase/nio и today.java.net/article/ 14.10.2009/очистка-файловой-системы-nio-2   -  person Petr Gladkikh    schedule 07.03.2011


Ответы (6)


С выпуском Java 7 для этого есть встроенный способ:

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

Важно отметить, что не все операционные системы предоставляют эту информацию. Я считаю, что в этих случаях это возвращает mtime, которое является временем последнего изменения.

Windows предоставляет время создания.

person ajon    schedule 06.06.2013

Несколько дней назад я написал небольшой тестовый класс, надеюсь, он вам поможет:

// 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 失败");
            }
        }
    }
}
person LiuYan 刘研    schedule 28.07.2010
comment
Мне так помогло! Спасибо! - person Jochen Reinschlüssel; 15.10.2013

Я сам исследовал это, но мне нужно что-то, что будет работать на платформах Windows/*nix.

Один пост SO содержит несколько ссылок на реализации Posix JNI.

В частности, JNA-POSIX реализует методы получения статистики файлов с реализациями для Windows, BSD, Solaris, Linux и OSX.

В целом, это выглядит очень многообещающе, поэтому я очень скоро опробую его на своем собственном проекте.

person Mike Houston    schedule 03.02.2010

Библиотека 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 и выше.

person Peter    schedule 11.01.2013

Мне нравится ответ на jGuru, в котором перечислены варианты использования JNI, чтобы получить ответ. Это может оказаться быстрее, чем обстрел, и вы можете столкнуться с другими ситуациями, такими как эта, которые необходимо реализовать специально для Windows.

Кроме того, если вам когда-нибудь понадобится портировать на другую платформу, вы также можете портировать свою библиотеку и просто вернуть -1 для ответа на этот вопрос на *ix.

person Joseph Gordon    schedule 28.08.2008

Это базовый пример в 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());
    }
person Jorgesys    schedule 24.09.2015