กำหนดวันที่สร้างไฟล์ใน Java


102

มีคำถามที่คล้ายกันกับของฉันใน StackOverflow ( วิธีรับวันที่สร้างไฟล์ใน Java ) แต่คำตอบไม่มีอยู่จริงเนื่องจาก OP มีความต้องการที่แตกต่างกันซึ่งสามารถแก้ไขได้ด้วยกลไกอื่น ๆ ฉันกำลังพยายามสร้างรายการไฟล์ในไดเร็กทอรีที่สามารถจัดเรียงตามอายุได้ดังนั้นจึงจำเป็นต้องมีวันที่สร้างไฟล์

ฉันไม่พบวิธีที่ดีในการทำสิ่งนี้หลังจากการอ่านเว็บมาก มีกลไกในการรับวันที่สร้างไฟล์หรือไม่?

BTW ซึ่งปัจจุบันอยู่ในระบบ Windows อาจต้องใช้สิ่งนี้เพื่อทำงานบนระบบ Linux เช่นกัน นอกจากนี้ฉันไม่สามารถรับประกันได้ว่าจะมีการปฏิบัติตามหลักการตั้งชื่อไฟล์โดยที่วันที่ / เวลาที่สร้างถูกฝังอยู่ในชื่อ


2
เอาล่ะหลังจากการพูดคุยและการตรวจสอบระบบไฟล์มากขึ้นเราได้ตัดสินใจว่าการใช้การแก้ไขครั้งล่าสุดนั้นเพียงพอแล้วเนื่องจากน่าจะต้องได้รับการตรวจสอบพร้อมกับวันที่สร้าง ทั้งสองอย่างจะต้องได้รับการตรวจสอบเพื่อดูว่าไฟล์เก่าถูกแก้ไขเมื่อเร็ว ๆ นี้หรือไม่และยังคงเปิดใช้งานอยู่ ดังนั้นให้ตรวจสอบไฟล์ที่แก้ไขมากที่สุดในอดีต ขอบคุณสำหรับทุกท่าน. BTW ฉันชอบใช้ nio แต่รสชาติของ Linux ที่นี่ไม่รองรับการสร้างไฟล์อยู่ดี
ทอดด์

คำตอบ:


165

Java nioมีอ็อพชันในการเข้าถึง creationTime และ meta-data อื่น ๆ ตราบเท่าที่ระบบไฟล์มีให้ ตรวจสอบการเชื่อมโยงนี้ออก

ตัวอย่างเช่น (จัดทำตามความคิดเห็นของ @ 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
สิ่งนี้จะดีที่สุด แต่เป็น Java 7 เรายังคงใช้ 6 อยู่ แต่ฉันจะตรวจสอบตัวเลือกการอัปเกรดของเรา
ทอดด์

1
ยอดเยี่ยม. ฉันต้องการ
RestInPeace

7
ใช้readAttributes(file.toPath(), BasicFileAttributes.class)อย่างอื่นที่คุณได้รับ: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 ไม่ห่วงคู่! ลองใช้logicbig.com/how-to/java/file-creation-date.htmlนี้
Socrates

1
วันที่สร้างไฟล์ไม่มีใน JDK 8 (อย่างน้อย) เนื่องจากstatxsyscall ถูกเพิ่มในเคอร์เนล Linux เวอร์ชันใหม่
St.Antario

15

ฉันได้แก้ไขปัญหานี้โดยใช้ JDK 7 ด้วยรหัสนี้:

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

จากการติดตามคำถามนี้ - เนื่องจากเกี่ยวข้องกับเวลาในการสร้างโดยเฉพาะและกล่าวถึงการได้รับผ่านคลาส nio ใหม่ดูเหมือนว่าตอนนี้ในการใช้งาน JDK7 คุณจะไม่โชคดี ภาคผนวก: พฤติกรรมเดียวกันอยู่ใน OpenJDK7

ในระบบไฟล์ Unix คุณไม่สามารถเรียกการประทับเวลาการสร้างได้คุณเพียงแค่ได้รับสำเนาของเวลาแก้ไขล่าสุด เศร้ามาก แต่น่าเสียดายที่เป็นจริง ฉันไม่แน่ใจว่าทำไมถึงเป็นเช่นนั้น แต่โค้ดจึงทำเช่นนั้นโดยเฉพาะดังต่อไปนี้จะแสดงให้เห็น

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
คุณรู้วิธีทำสำหรับ Android หรือไม่? BasicFileAttributes ไม่พร้อมใช้งานในตัว API ที่นั่น ...
นักพัฒนา android

นี่เป็นเรื่องจริงแม้แต่การโทรหาstatก็ไม่ได้ผล เว้นแต่ว่าคุณจะรันเคอร์เนลที่สูงกว่า 4.11 โดยมี glibc สูงกว่า 2.28 และ coreutils สูงกว่า 8.31 statจะรายงานการเกิดของไฟล์ ดูคำตอบที่เกี่ยวข้องunix.stackexchange.com/questions/50177/birth-is-empty-on-ext4/…ปัจจุบัน JDK ไม่ได้ใช้ statx syscal
Brice

12

นี่คือตัวอย่างพื้นฐานของวิธีรับวันที่สร้างไฟล์Javaโดยใช้BasicFileAttributesคลาส:

   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());
}

ผู้ที่ต้องการใช้คลาสนี้ควรทราบว่าเริ่มจัดส่งใน Java 1.7
jwj

10

ในระบบ Windows คุณสามารถใช้ไลบรารีFileTimesฟรี

นี้จะง่ายขึ้นในอนาคตด้วยJava NIO.2 (JDK 7) และแพคเกจ

แต่จำไว้ว่าส่วนใหญ่ระบบไฟล์ลินุกซ์ไม่สนับสนุนการประทับเวลาการสร้างแฟ้ม


วิธีอื่นสำหรับเครื่อง linux ที่ไม่รองรับเวลาที่สร้างขึ้นหรือไม่?
Maverick

เพียงใช้ระบบไฟล์ที่รองรับการประทับเวลาการสร้างไฟล์ บทความ Wikipedia ที่เชื่อมโยงแนะนำ ext4 ซึ่งพบได้บ่อยในขณะนี้
davtom

9

API java.io.Fileรองรับเฉพาะการรับเวลาแก้ไขล่าสุด และอินเทอร์เน็ตก็เงียบมากในหัวข้อนี้เช่นกัน

เว้นแต่ฉันจะพลาดสิ่งสำคัญไลบรารี Java ตามที่เป็นอยู่ (ถึง แต่ยังไม่รวม Java 7) จะไม่มีความสามารถนี้ ดังนั้นหากคุณหมดหวังกับสิ่งนี้วิธีแก้ปัญหาหนึ่งคือเขียนโค้ด C (++) เพื่อเรียกรูทีนของระบบและเรียกโดยใช้ JNI ดูเหมือนว่างานนี้ส่วนใหญ่จะทำเพื่อคุณในห้องสมุดชื่อJNAแล้ว

คุณอาจยังต้องทำการเข้ารหัสเฉพาะระบบปฏิบัติการใน Java สำหรับสิ่งนี้เนื่องจากคุณอาจไม่พบการเรียกระบบเดียวกันใน Windows และ Unix / Linux / BSD / OS X


2
ใช่ Java 7 จะดีมากเพราะ nio ดูเหมือนจะมีสิ่งนี้ในคุณสมบัติพื้นฐาน ไม่เคยคิดว่าฉันจะบ่นว่าเกิดเร็วเกินไป! ;)
ทอดด์

7
เหตุผลที่Fileคลาสไม่มีความสามารถนี้ก็คือระบบไฟล์ส่วนใหญ่ไม่ได้ติดตามข้อมูลนี้ด้วยซ้ำ และผู้ที่ไม่เห็นด้วยเสมอว่าควรอัปเดตเมื่อใด
Syntactic

@Syntactic: จริงๆแล้วระบบไฟล์ส่วนใหญ่ติดตามข้อมูลนี้ ข้อยกเว้น ได้แก่ ext <= 3 และ Reiser FAT, NTFS, HFS, ZFS และ ext4 รองรับ แต่มันช้าในการเผยแพร่ผ่านทุกเลเยอร์ของ Linux รวมถึงไลบรารีและคำสั่งต่างๆเพื่อให้ใช้กันอย่างแพร่หลาย
ฮิปปี้

@Carl ใน linux ฉันได้รับการแก้ไขและวันที่สร้างเหมือนกันในขณะที่ใช้ Java NIO เป็นพฤติกรรมปกติหรือไม่?
Jayesh Dhandha

@JayeshDhandha ถ้าไม่มีอะไรแก้ไขไฟล์หลังจากสร้างแล้วฉันคาดว่าเวลาในการสร้างและแก้ไขจะเท่ากัน คุณสามารถลองเปลี่ยนโดยใช้touchเพื่อเปลี่ยนเวลา mod แล้วตรวจสอบอีกครั้ง
คาร์ลสโมทริกซ์

1

ใน java1.7 + คุณสามารถใช้รหัสนี้เพื่อรับเวลาในการสร้างไฟล์!

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());
    }

คุณช่วยอธิบายให้ละเอียดได้ไหมว่าทำไมเราถึงต้องเร่งรีบขนาดInstant.ofEpochMilli(date)นี้ ขอบคุณ
Kirill Karmazin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.