Xác định ngày tạo tệp trong Java


102

Có một câu hỏi tương tự khác dành cho tôi trên StackOverflow ( Cách lấy ngày tạo tệp trong Java ), nhưng câu trả lời không thực sự ở đó vì OP có một nhu cầu khác có thể được giải quyết thông qua các cơ chế khác. Tôi đang cố gắng tạo một danh sách các tệp trong một thư mục có thể được sắp xếp theo độ tuổi, do đó cần có ngày tạo tệp.

Tôi không tìm ra cách nào tốt để thực hiện việc này sau nhiều lần dò tìm trên mạng. Có cơ chế nào để lấy ngày tạo tệp không?

BTW, hiện có trên hệ thống Windows, có thể cần điều này để hoạt động trên hệ thống Linux. Ngoài ra, tôi không thể đảm bảo rằng quy ước đặt tên tệp sẽ được tuân theo trong đó ngày / giờ tạo được nhúng vào tên.


2
Được rồi, sau nhiều cuộc thảo luận và điều tra về hệ thống tệp, chúng tôi đã quyết định rằng việc sử dụng bản sửa đổi cuối cùng là đủ vì nó có thể phải được kiểm tra cùng với ngày tạo. Cả hai sẽ cần được kiểm tra để xác định xem một tệp cũ đã được sửa đổi gần đây và do đó vẫn hoạt động hay không. Vì vậy, chỉ cần kiểm tra tệp được sửa đổi xa nhất trong quá khứ. Cám ơn vì tất cả đóng góp. BTW, tôi rất thích sử dụng nio, nhưng hương vị Linux ở đây không hỗ trợ tạo tệp.
Todd

Câu trả lời:


163

Java nio có các tùy chọn để truy cập thời gian tạo và các siêu dữ liệu khác miễn là hệ thống tệp cung cấp nó. Kiểm tra liên kết này ra

Ví dụ (Được cung cấp dựa trên nhận xét của @ ydaetskcoR):

Path file = ...;
BasicFileAttributes attr = Files.readAttributes(file, BasicFileAttributes.class);

System.out.println("creationTime: " + attr.creationTime());
System.out.println("lastAccessTime: " + attr.lastAccessTime());
System.out.println("lastModifiedTime: " + attr.lastModifiedTime());

16
Điều này sẽ là tốt nhất, nhưng đó là Java 7. Chúng tôi vẫn đang sử dụng 6, nhưng tôi sẽ điều tra các tùy chọn nâng cấp của chúng tôi.
Todd

1
Tuyệt diệu. Chính xác là tôi cần.
RestInPeace

7
sử dụng readAttributes(file.toPath(), BasicFileAttributes.class)khác mà bạn nhận được:no suitable method found for readAttributes(File,Class<BasicFileAttributes>) method Files.<A>readAttributes(Path,Class<A>,LinkOption...) is not applicable (cannot infer type-variable(s) A (argument mismatch; File cannot be converted to Path))
Hooli

1
@Hooli Không phải lo lắng, anh bạn! Hãy thử logicbig.com/how-to/java/file-creation-date.html này .
Socrates

1
Ngày tạo tệp không khả dụng trên JDK 8 (ít nhất là) vì statxsyscall đã được thêm vào phiên bản hạt nhân Linux mới hơn.
St.Antario

15

Tôi đã giải quyết vấn đề này bằng cách sử dụng JDK 7 với mã này:

package FileCreationDate;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.Date;
import java.util.concurrent.TimeUnit;

public class Main
{
    public static void main(String[] args) {

        File file = new File("c:\\1.txt");
        Path filePath = file.toPath();

        BasicFileAttributes attributes = null;
        try
        {
            attributes =
                    Files.readAttributes(filePath, BasicFileAttributes.class);
        }
        catch (IOException exception)
        {
            System.out.println("Exception handled when trying to get file " +
                    "attributes: " + exception.getMessage());
        }
        long milliseconds = attributes.creationTime().to(TimeUnit.MILLISECONDS);
        if((milliseconds > Long.MIN_VALUE) && (milliseconds < Long.MAX_VALUE))
        {
            Date creationDate =
                    new Date(attributes.creationTime().to(TimeUnit.MILLISECONDS));

            System.out.println("File " + filePath.toString() + " created " +
                    creationDate.getDate() + "/" +
                    (creationDate.getMonth() + 1) + "/" +
                    (creationDate.getYear() + 1900));
        }
    }
}

13

Theo dõi câu hỏi này - vì nó liên quan cụ thể đến thời gian tạo và thảo luận về việc lấy nó thông qua các lớp nio mới - có vẻ như ngay bây giờ trong việc triển khai JDK7, bạn đã gặp may. Phụ lục: hành vi tương tự cũng có trong OpenJDK7.

Trên hệ thống tệp Unix, bạn không thể truy xuất dấu thời gian tạo, bạn chỉ cần nhận bản sao của lần sửa đổi cuối cùng. Thật đáng buồn, nhưng tiếc là sự thật. Tôi không chắc tại sao lại như vậy nhưng mã thực hiện điều đó một cách cụ thể như sau sẽ chứng minh.

import java.io.IOException;
import java.nio.file.*;
import java.nio.file.attribute.*;

public class TestFA {
  static void getAttributes(String pathStr) throws IOException {
    Path p = Paths.get(pathStr);
    BasicFileAttributes view
       = Files.getFileAttributeView(p, BasicFileAttributeView.class)
              .readAttributes();
    System.out.println(view.creationTime()+" is the same as "+view.lastModifiedTime());
  }
  public static void main(String[] args) throws IOException {
    for (String s : args) {
        getAttributes(s);
    }
  }
}

1
Bạn có biết làm thế nào để làm điều đó cho Android? BasicFileAttributes là không có sẵn như xây dựng trong API có ...
android phát triển

Điều này thực sự đúng, ngay cả một cuộc gọi đến statkhông hoạt động. Trừ khi bạn tình cờ chạy kernel cao hơn 4.11 với glibc cao hơn 2.28 và coreutils cao hơn 8.31, khi đó statsẽ báo cáo sự ra đời của tệp. Xem câu trả lời liên quan unix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/… Hiện tại JDK không sử dụng statx syscal.
Brice

12

Đây là một ví dụ cơ bản về cách lấy ngày tạo tệp Javabằng BasicFileAttributeslớp:

   Path path = Paths.get("C:\\Users\\jorgesys\\workspaceJava\\myfile.txt");
    BasicFileAttributes attr;
    try {
    attr = Files.readAttributes(path, BasicFileAttributes.class);
    System.out.println("Creation date: " + attr.creationTime());
    //System.out.println("Last access date: " + attr.lastAccessTime());
    //System.out.println("Last modified date: " + attr.lastModifiedTime());
    } catch (IOException e) {
    System.out.println("oops error! " + e.getMessage());
}

Những người muốn sử dụng lớp này nên lưu ý rằng nó đã bắt đầu xuất xưởng trong Java 1.7.
jwj 13/03/18

9

API của java.io.Filechỉ hỗ trợ việc sửa đổi lần cuối . Và Internet cũng rất yên tĩnh về chủ đề này.

Trừ khi tôi bỏ lỡ điều gì đó quan trọng, thư viện Java hiện tại (lên đến nhưng chưa bao gồm Java 7) không bao gồm khả năng này. Vì vậy, nếu bạn đang tuyệt vọng cho điều này, một giải pháp sẽ là viết một số mã C (++) để gọi các quy trình hệ thống và gọi nó bằng JNI. Hầu hết công việc này dường như đã được thực hiện cho bạn trong một thư viện có tên là JNA .

Tuy nhiên, bạn có thể vẫn cần thực hiện một chút mã hóa hệ điều hành cụ thể trong Java cho việc này, vì có thể bạn sẽ không tìm thấy các lệnh gọi hệ thống tương tự có sẵn trong Windows và Unix / Linux / BSD / OS X.


2
Vâng, Java 7 sẽ rất tuyệt vì nio dường như có điều này trong các thuộc tính cơ bản. Chưa bao giờ tôi nghĩ rằng tôi sẽ phàn nàn về việc sinh quá sớm! ;)
Todd

6
Lý do Filelớp không có khả năng này là hầu hết các hệ thống tệp thậm chí không theo dõi thông tin này. Và những thứ không phải lúc nào cũng đồng ý về thời điểm nên cập nhật.
Cú pháp

@Syntactic: Trên thực tế, hầu hết các hệ thống tệp đều theo dõi thông tin này . Các ngoại lệ bao gồm ext <= 3 và Reiser. FAT, NTFS, HFS, ZFS và ext4 hỗ trợ nó. Nhưng nó chậm được phổ biến qua tất cả các lớp của Linux cũng như các thư viện và lệnh để làm cho nó được sử dụng phổ biến.
hippietrail

@Carl Trong linux, tôi nhận được ngày sửa đổi và tạo giống như khi sử dụng Java NIO. Đó có phải là hành vi bình thường?
Jayesh Dhandha

@JayeshDhandha, nếu không có gì sửa đổi tệp sau khi nó được tạo, tôi sẽ mong đợi thời gian tạo và sửa đổi bằng nhau. Bạn có thể thử thay đổi điều đó bằng cách sử dụng touchđể thay đổi thời gian mod và sau đó kiểm tra lại.
Carl Smotricz

9

Trên hệ thống Windows, bạn có thể sử dụng FileTimes miễn phí thư viện .

Điều này sẽ dễ dàng hơn trong tương lai với Java NIO.2 (JDK 7) và gói java.nio.file.attribute .

Nhưng hãy nhớ rằng hầu hết các hệ thống tệp Linux không hỗ trợ dấu thời gian tạo tệp .


Bất kỳ cách nào khác cho các máy Linux không hỗ trợ thời gian tạo?
Maverick

Chỉ cần sử dụng hệ thống tệp hỗ trợ dấu thời gian tạo tệp. Bài báo Wikipedia được liên kết đề xuất ext4 khá phổ biến hiện nay.
davtom

1

trong java1.7 + Bạn có thể sử dụng mã này để có thời gian tạo tệp!

private static LocalDateTime getCreateTime(File file) throws IOException {
        Path path = Paths.get(file.getPath());
        BasicFileAttributeView basicfile = Files.getFileAttributeView(path, BasicFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
        BasicFileAttributes attr = basicfile.readAttributes();
        long date = attr.creationTime().toMillis();
        Instant instant = Instant.ofEpochMilli(date);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }

bạn có thể vui lòng giải thích tại sao chúng tôi cần sự hối hả này với Instant.ofEpochMilli(date). Cảm ơn
Kirill Karmazin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.