2014-07-17 13 views
8

Wenn ich die mtime einer Datei aus Java mit Files.getLastModifiedTime lesen, wird der Rückgabewert auf ganze Sekunden abgeschnitten. Ich weiß, dass dies auf anderen Systemen funktioniert, um MIMEs mit Millisekundenauflösung zu bekommen, also was könnte anders an meinem sein?Holen Sie sich Datei Mtime mit Millisekunden Auflösung von Java

ist der komplette Standalone-Test, der kompiliert und läuft:

import java.nio.file.attribute.FileTime; 
import java.nio.file.Files; 
import java.nio.file.Paths; 
public class Test { 
    public static void main(String[] args) throws java.io.IOException { 
    FileTime timestamp = Files.getLastModifiedTime(Paths.get("/tmp/test")); 
    System.out.println(timestamp.toMillis()); 
    } 
} 

Der Ausgang ist (mit meiner speziellen Testdatei) 1405602038000, während ls zeigt:

$ ls --full-time /tmp/test                                                  
-rw-rw-r-- 1 daniel daniel 0 2014-07-17 16:00:38.413008992 +0300 /tmp/test 

Ich würde die Java erwarten Ausgabe soll 1405602038413 sein.

Ich bin auf Linux mit ext4 ausgeführt. Ich habe versucht sowohl openjdk 1.7 und Oracle jdk 1.8.

Antwort

7

Die Fähigkeit Dateizeitstempel auf * nix-Systemen zu bekommen mit einer höheren Genauigkeit in Java 8 von this commit jedoch hinzugefügt wurde, auf der nativen Seite erfordert es POSIX 2008 Compliance:

#if (_POSIX_C_SOURCE >= 200809L) || defined(__solaris__) 
    (*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->st_atim.tv_nsec); 
    (*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->st_mtim.tv_nsec); 
    (*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->st_ctim.tv_nsec); 
#endif 

Und offenbar die Java-Build, das Sie verwenden, stellt es nicht ein, so dass ein Nanosekunden-Teil des Zeitstempels nicht verfügbar ist und Null bleibt.

-4

Sie können die einfache Datumsformat verwenden, um Zeit anzuzeigen ist Millisekunden:

java.nio.file.attribute.FileTime time = java.nio.file.Files.getLastModifiedTime(java.nio.file.Paths.get("/tmp/test")) 
java.text.SimpleDateFormat dateformat = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); 
System.out.println(dateformat.format(time.toMillis())); 
+1

Sie mißverstehen gibt. Der von 'time.toMillis' zurückgegebene Wert ist bereits auf die Auflösung der ganzen Sekunde verkürzt (d. H. Endet immer in drei Nullen). Das ist falsch. – danarmak

+0

Das scheint seltsam, denn wenn ich es auf meinem Computer versuche, bekomme ich Millisekunden Auflösung. – lerobyte

+0

Ich bin mir bewusst, dass es für andere funktioniert (Ich habe die Frage bearbeitet, um das zu klären), aber es funktioniert hier nicht und ich versuche herauszufinden, warum. – danarmak

3

ich auf den Quellcode sah:

Im Java 7 Fall wird die Methode der letzten Änderung Zeitstempel gibt mit 1 zweite Präzision:

Im Java 8 Fall, es sieht aus wie sollte es mikrosekundengenau geben:

Aber in jedem Fall wird der Code scheint keinen Weg, um die bekommen Zeitstempel mit einer anderen Genauigkeit.

+0

[Dieses '# if'] (http://hg.openjdk.java.net/jdk8/jdk8/jdk/datei/687fd7c7986d/src/solaris/native/sonne/nio/fs/UnixNativeDispatcher.C# l437) scheint verwandt zu sein. Ich bin in der Lage, das Problem mit Oracle Java 8 auf Ubuntu zu reproduzieren. – izstas

+1

Wenn ich mit einem Debugger auf die 'UnixFileAttributes.st_mtime' schaue, ist es schon in ganzen Sekunden. Auf der nativen Seite stimmt etwas nicht. Außerdem kann ich Millis auch nicht in Java 8 (oracle build, nicht openjdk) bekommen. Kannst du tatsächlich Millis bekommen, wenn du Java 8 startest? – danarmak

+1

@izstas Bingo! Ich bin auch auf Ubuntu. Jetzt müssen wir nur wissen, warum Ubuntu-Builds (und der Oracle-Build!) Nicht die POSIX2008-Konformität festlegen. Werden Builds für andere Betriebssysteme oder Distributionen erstellt? Wofür laufen die Leute, für die dieser Code funktioniert? Wenn Sie dies zu einer Antwort machen, werde ich es akzeptieren, und danke! – danarmak

0

Es scheint in Java festgelegt werden 9

  • Oracle JDK 9.0.4 - Files.getLastModifiedTime gibt Millisekundenauflösung
  • Oracle JDK 1.8.162 - Files.getLastModifiedTime zweite Auflösung