17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 8181493 26 * @summary Verify that nanosecond precision is maintained for file timestamps 27 * @requires (os.family == "linux") | (os.family == "mac") | (os.family == "solaris") 28 */ 29 30 import java.io.IOException; 31 import java.nio.file.Files; 32 import java.nio.file.FileStore; 33 import java.nio.file.Path; 34 import java.nio.file.attribute.BasicFileAttributes; 35 import java.nio.file.attribute.BasicFileAttributeView; 36 import java.nio.file.attribute.FileTime; 37 import java.time.Instant; 38 import java.time.ZoneId; 39 import java.time.ZoneOffset; 40 import java.time.format.DateTimeFormatter; 41 import java.util.Arrays; 42 import java.util.concurrent.TimeUnit; 43 44 public class SetTimesNanos { 45 public static void main(String[] args) throws IOException, 46 InterruptedException { 47 48 Path dirPath = Path.of("test"); 49 Path dir = Files.createDirectory(dirPath); 50 FileStore store = Files.getFileStore(dir); 51 System.out.format("FileStore: %s on %s (%s)%n", dir, store.name(), 52 store.type()); 53 if (System.getProperty("os.name").toLowerCase().startsWith("mac") && 54 store.type().equalsIgnoreCase("hfs")) { 55 System.err.println 56 ("HFS on macOS does not have nsec timestamps: skipping test"); 57 return; 58 } 59 testNanos(dir); 60 61 Path file = Files.createFile(dir.resolve("test.dat")); 62 testNanos(file); 63 } 64 65 private static void testNanos(Path path) throws IOException { 66 // Set modification and access times 67 // Time stamp = "2017-01-01 01:01:01.123456789"; 68 long timeNanos = 1_483_261_261L*1_000_000_000L + 123_456_789L; 69 FileTime pathTime = FileTime.from(timeNanos, TimeUnit.NANOSECONDS); 70 BasicFileAttributeView view = 71 Files.getFileAttributeView(path, BasicFileAttributeView.class); 72 view.setTimes(pathTime, pathTime, null); 73 74 // Read attributes 75 BasicFileAttributes attrs = 76 Files.readAttributes(path, BasicFileAttributes.class); 77 78 // Check timestamps 79 String[] timeNames = new String[] {"modification", "access"}; 80 FileTime[] times = new FileTime[] {attrs.lastModifiedTime(), 81 attrs.lastAccessTime()}; 82 for (int i = 0; i < timeNames.length; i++) { 83 long nanos = times[i].to(TimeUnit.NANOSECONDS); 84 if (nanos != timeNanos) { 85 throw new RuntimeException("Expected " + timeNames[i] + 86 " timestamp to be '" + timeNanos + "', but was '" + 87 nanos + "'"); 88 } 89 } 90 } 91 } | 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* @test 25 * @bug 8181493 26 * @summary Verify that nanosecond precision is maintained for file timestamps 27 * @requires (os.family == "linux") | (os.family == "mac") | (os.family == "solaris") 28 */ 29 30 import java.io.IOException; 31 import java.nio.file.Files; 32 import java.nio.file.FileStore; 33 import java.nio.file.Path; 34 import java.nio.file.attribute.BasicFileAttributes; 35 import java.nio.file.attribute.BasicFileAttributeView; 36 import java.nio.file.attribute.FileTime; 37 import java.util.Set; 38 import java.util.concurrent.TimeUnit; 39 40 public class SetTimesNanos { 41 public static void main(String[] args) throws IOException, 42 InterruptedException { 43 44 Path dirPath = Path.of("test"); 45 Path dir = Files.createDirectory(dirPath); 46 FileStore store = Files.getFileStore(dir); 47 String type = store.type().toLowerCase(); 48 boolean strict = Set.of("apfs", "ext4", "xfs", "zfs").contains(type); 49 System.out.format("FileStore: %s on %s (%s, strict=%s)%n", 50 dir, store.name(), store.type(), strict); 51 testNanos(dir, strict); 52 53 Path file = Files.createFile(dir.resolve("test.dat")); 54 testNanos(file, strict); 55 } 56 57 private static void testNanos(Path path, boolean strict) throws IOException { 58 // Set modification and access times 59 // Time stamp = "2017-01-01 01:01:01.123456789"; 60 long timeNanos = 1_483_261_261L*1_000_000_000L + 123_456_789L; 61 FileTime pathTime = FileTime.from(timeNanos, TimeUnit.NANOSECONDS); 62 BasicFileAttributeView view = 63 Files.getFileAttributeView(path, BasicFileAttributeView.class); 64 view.setTimes(pathTime, pathTime, null); 65 66 // Read attributes 67 BasicFileAttributes attrs = 68 Files.readAttributes(path, BasicFileAttributes.class); 69 70 // Check timestamps 71 String[] timeNames = new String[] {"modification", "access"}; 72 FileTime[] times = new FileTime[] {attrs.lastModifiedTime(), 73 attrs.lastAccessTime()}; 74 for (int i = 0; i < timeNames.length; i++) { 75 long nanos = times[i].to(TimeUnit.NANOSECONDS); 76 if (nanos != timeNanos) { 77 boolean failed = strict; 78 if (!failed) { 79 String expected = String.valueOf(timeNanos); 80 String actual = String.valueOf(nanos); 81 int len = actual.length(); 82 failed = len != expected.length(); 83 if (!failed) { 84 int nz = 0; 85 for (int j = len - 1; j >= 0; j--) { 86 if (actual.charAt(j) == '0') { 87 nz++; 88 } else { 89 break; 90 } 91 } 92 failed = (nz % 3) != 0 || 93 !actual.substring(0, len - nz).equals( 94 expected.substring(0, len - nz)); 95 } 96 } 97 if (failed) { 98 throw new RuntimeException("Expected " + timeNames[i] + 99 " timestamp to be '" + timeNanos + "', but was '" + 100 nanos + "'"); 101 } 102 } 103 } 104 } 105 } |