blob: afadb07b97ea57a0dfeeef3775cff3a30a8ef5c4 [file] [log] [blame]
package jnr.posix;
import jnr.constants.platform.Access;
import jnr.constants.platform.Fcntl;
import jnr.constants.platform.Errno;
import jnr.constants.platform.OpenFlags;
import jnr.ffi.Pointer;
import jnr.posix.util.Platform;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
public class FileTest {
private static POSIX posix;
@BeforeClass
public static void setUpClass() throws Exception {
posix = POSIXFactory.getPOSIX(new DummyPOSIXHandler(), true);
}
@Test
public void utimesTest() throws Throwable {
// FIXME: On Windows this is working but providing wrong numbers and therefore getting wrong results.
if (!Platform.IS_WINDOWS) {
File f = File.createTempFile("utimes", null);
int rval = posix.utimes(f.getAbsolutePath(), new long[]{800, 200}, new long[]{900, 300});
assertEquals("utimes did not return 0", 0, rval);
FileStat stat = posix.stat(f.getAbsolutePath());
assertEquals("atime seconds failed", 800, stat.atime());
assertEquals("mtime seconds failed", 900, stat.mtime());
// The nano secs part is available in other stat implementations. We really just want to verify that the
// nsec portion of the timeval is passed through to the POSIX call.
// Mac seems to fail this test sporadically.
if (stat instanceof NanosecondFileStat && !Platform.IS_MAC) {
NanosecondFileStat linuxStat = (NanosecondFileStat) stat;
assertEquals("atime useconds failed", 200000, linuxStat.aTimeNanoSecs());
assertEquals("mtime useconds failed", 300000, linuxStat.mTimeNanoSecs());
}
f.delete();
}
}
@Test
public void utimesDefaultValuesTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File f = File.createTempFile("utimes", null);
long oldTime = posix.stat(f.getAbsolutePath()).mtime();
Thread.sleep(2000);
int rval = posix.utimes(f.getAbsolutePath(), null, null);
assertEquals("utimes did not return 0", 0, rval);
FileStat stat = posix.stat(f.getAbsolutePath());
assertTrue("atime failed", stat.atime() > oldTime);
assertTrue("mtime failed", stat.mtime() > oldTime);
f.delete();
}
}
@Test
public void utimesPointerTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File f = File.createTempFile("utimes", null);
Pointer times = jnr.ffi.Runtime.getSystemRuntime().getMemoryManager().allocateDirect(8 * 4); // long[2][2] == 4 longs.
times.putLong(0, 800);
times.putLong(8, 200);
times.putLong(16, 900);
times.putLong(24, 300);
int rval = posix.utimes(f.getAbsolutePath(), times);
assertEquals("utimes did not return 0", 0, rval);
FileStat stat = posix.stat(f.getAbsolutePath());
assertEquals("atime seconds failed", 800, stat.atime());
assertEquals("mtime seconds failed", 900, stat.mtime());
// The nano secs part is available in other stat implementations. We use Linux x86_64 because it's
// representative. We really just want to verify that the usec portion of the timeval is passed throug
// to the POSIX call.
if (hasNanosecondPrecision(stat)) {
NanosecondFileStat linuxStat = (NanosecondFileStat) stat;
// assertEquals("atime useconds failed", 200000, linuxStat.aTimeNanoSecs());
assertEquals("mtime useconds failed", 300000, linuxStat.mTimeNanoSecs());
}
f.delete();
}
}
@Test
public void utimensatAbsolutePath() throws Throwable {
File file = File.createTempFile("utimensat", null);
utimensat(file, 0);
}
@Test
public void utimensatRelativePath() throws Throwable {
String path = "utimensat";
File file = new File(path);
file.createNewFile();
int parentFd = posix.open(".", OpenFlags.O_DIRECTORY.intValue(), 0444);
utimensat(file, parentFd);
}
@Test
public void futimens() throws Throwable {
File file = File.createTempFile("futimens", null);
FileStat fileStat = posix.stat(file.getPath());
if (!hasNanosecondPrecision(fileStat)) {
file.delete();
return;
}
long atimeSeconds = fileStat.atime()+1;
long mtimeSeconds = fileStat.mtime()-1;
long atimeNanoSeconds = 123456789;
long mtimeNanoSeconds = 135;
int fd = posix.open(file.getAbsolutePath(), OpenFlags.O_RDWR.intValue(), 0444);
posix.futimens(fd,
new long[] {atimeSeconds, atimeNanoSeconds},
new long[] {mtimeSeconds, mtimeNanoSeconds});
assertStatNanoSecond(file, atimeSeconds, atimeNanoSeconds, mtimeSeconds, mtimeNanoSeconds);
}
@Test
public void lutimesTest() throws Throwable {
// FIXME: On Windows this is working but providing wrong numbers and therefore getting wrong results.
if (!Platform.IS_WINDOWS) {
File f1 = File.createTempFile("lutimes", null);
File f2 = new File(f1.getParentFile(), "lutimes-link");
posix.symlink(f1.getAbsolutePath(), f2.getAbsolutePath());
int rval = posix.utimes(f1.getAbsolutePath(), new long[]{800, 0}, new long[]{900, 0});
assertEquals("utimes did not return 0", 0, rval);
rval = posix.lutimes(f2.getAbsolutePath(), new long[]{1800, 0}, new long[]{1900, 0});
assertEquals("lutimes did not return 0", 0, rval);
FileStat stat = posix.stat(f1.getAbsolutePath());
assertEquals("atime seconds failed", 800, stat.atime());
assertEquals("mtime seconds failed", 900, stat.mtime());
stat = posix.lstat(f2.getAbsolutePath());
assertEquals("atime seconds failed", 1800, stat.atime());
assertEquals("mtime seconds failed", 1900, stat.mtime());
f1.delete();
f2.delete();
}
}
@Test
public void futimeTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File f = File.createTempFile("jnr-posix-futime", "tmp");
long oldTime = posix.stat(f.getAbsolutePath()).mtime();
Thread.sleep(2000);
int fd = posix.open(f.getAbsolutePath(), OpenFlags.O_RDWR.intValue(), 0666);
int rval = posix.futimes(fd, null, null);
assertEquals("futime did not return 0", 0, rval);
long newTime = posix.stat(f.getAbsolutePath()).mtime();
f.delete();
assertTrue("mtime failed", newTime > oldTime);
}
}
@Test
public void linkTest() throws Throwable {
File f1 = File.createTempFile("utime", null);
File f2 = new File(f1.getAbsolutePath() + "link");
int rval = posix.link(f1.getAbsolutePath(), f2.getAbsolutePath());
assertEquals("link did not return 0", 0, rval);
assertTrue("Link was not created", f2.exists());
f1.delete();
f2.delete();
}
@Test
public void mkdirRelativeTest() throws Throwable {
File dir = new File("tmp");
int rval = posix.mkdir(dir.getPath(), 0);
assertEquals("mkdir did not return 0", 0, rval);
assertTrue("Directory was not created", dir.exists());
dir.delete();
}
@Test
public void mkdirAbsoluteTest() throws Throwable {
File dir = new File("tmp");
int rval = posix.mkdir(dir.getAbsolutePath(), 0);
assertEquals("mkdir did not return 0", 0, rval);
assertTrue("Directory was not created", dir.exists());
dir.delete();
}
@Test
public void flockTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File tmp = File.createTempFile("flockTest", "tmp");
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
RandomAccessFile raf2 = new RandomAccessFile(tmp, "rw");
FileChannel fc = raf.getChannel();
FileChannel fc2 = raf2.getChannel();
FileDescriptor FD = JavaLibCHelper.getDescriptorFromChannel(fc);
FileDescriptor FD2 = JavaLibCHelper.getDescriptorFromChannel(fc2);
int fd = JavaLibCHelper.getfdFromDescriptor(FD);
int fd2 = JavaLibCHelper.getfdFromDescriptor(FD2);
assertEquals(0, posix.flock(fd, 1)); // LOCK_SH
assertEquals(0, posix.flock(fd, 8)); // LOCK_UN
assertEquals(0, posix.flock(fd, 2)); // LOCK_EX
assertEquals(-1, posix.flock(fd2, 2 | 4)); // LOCK_EX | LOCK_NB
assertEquals(0, posix.flock(fd, 8)); // LOCK_UN
}
}
@Test
public void dupTest() throws Throwable {
File tmp = File.createTempFile("dupTest", "tmp");
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
FileChannel fileChannel = raf.getChannel();
int fileDescriptor = getFdFromDescriptor(JavaLibCHelper.getDescriptorFromChannel(fileChannel));
byte[] outContent = "foo".getBytes();
FileDescriptor newFileDescriptor = toDescriptor(posix.dup(fileDescriptor));
new FileOutputStream(toDescriptor(fileDescriptor)).write(outContent);
raf.seek(0);
byte[] inContent = new byte[outContent.length];
new FileInputStream(newFileDescriptor).read(inContent, 0, 3);
assertArrayEquals(inContent, outContent);
}
public static final int SEEK_SET = 0;
@Test
public void dup2Test() throws Throwable {
File tmp = File.createTempFile("dupTest", "tmp");
int oldFd = posix.open(tmp.getAbsolutePath(), OpenFlags.O_RDWR.intValue(), 0666);
int newFd = 1000;
byte[] outContent = "foo".getBytes();
// NB: Windows differs a bit from POSIX's return value. Both will return -1 on failure, but Windows will return
// 0 upon success, while POSIX will return the new FD. Since we already know what the FD will be if the call
// is successful, it's easy to make code that works with both forms. But it is something to watch out for.
assertNotEquals(-1, posix.dup2(oldFd, newFd));
FileDescriptor newFileDescriptor = toDescriptor(newFd);
new FileOutputStream(toDescriptor(oldFd)).write(outContent);
posix.lseek(newFd, SEEK_SET, 0);
byte[] inContent = new byte[outContent.length];
new FileInputStream(newFileDescriptor).read(inContent, 0, 3);
assertArrayEquals(inContent, outContent);
}
@Test
public void fcntlDupfdTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File tmp = File.createTempFile("fcntlTest", "tmp");
int fd = posix.open(tmp.getPath(), OpenFlags.O_RDWR.intValue(), 0444);
byte[] outContent = "foo".getBytes();
// NOTE: This test used to call without the third argument, but this leads to undefined behavior.
// See https://github.com/jnr/jnr-posix/issues/144
int newFd = posix.fcntl(fd, Fcntl.F_DUPFD, 0);
new FileOutputStream(JavaLibCHelper.toFileDescriptor(fd)).write(outContent);
posix.lseek(fd, SEEK_SET, 0);
byte[] inContent = new byte[outContent.length];
new FileInputStream(JavaLibCHelper.toFileDescriptor(newFd)).read(inContent, 0, 3);
assertArrayEquals(inContent, outContent);
}
}
@Test
public void fcntlDupfdWithArgTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File tmp = File.createTempFile("dupTest", "tmp");
int oldFd = JavaLibCHelper.getfdFromDescriptor(JavaLibCHelper.getDescriptorFromChannel(
new RandomAccessFile(tmp, "rw").getChannel()));
int newFd = JavaLibCHelper.getfdFromDescriptor(JavaLibCHelper.getDescriptorFromChannel(
new RandomAccessFile(tmp, "rw").getChannel()));
byte[] outContent = "foo".getBytes();
int expectedFd = 100;
int dupFd = posix.fcntl(oldFd, Fcntl.F_DUPFD, expectedFd);
new FileOutputStream(JavaLibCHelper.toFileDescriptor(newFd)).write(outContent);
byte[] inContent = new byte[outContent.length];
new FileInputStream(JavaLibCHelper.toFileDescriptor(dupFd)).read(inContent, 0, 3);
assertTrue(dupFd >= expectedFd);
assertArrayEquals(inContent, outContent);
}
}
@Test
public void closeTest() throws Throwable {
File tmp = File.createTempFile("closeTest", "tmp");
int fd = getFdFromDescriptor(JavaLibCHelper.getDescriptorFromChannel(new RandomAccessFile(tmp, "rw").getChannel()));
int result;
result = posix.close(fd);
assertEquals(0, result);
result = posix.close(fd);
assertEquals(-1, result);
// TODO (nirvdrum 06-May-15) We're not getting the correct errno value from Windows currently, so we need to skip this test.
if (!Platform.IS_WINDOWS) {
assertEquals(Errno.EBADF.intValue(), posix.errno());
}
}
@Test
public void unlinkTestNonWindows() throws Throwable {
if (! Platform.IS_WINDOWS) {
File tmp = File.createTempFile("unlinkTest", "tmp");
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
raf.write("hello".getBytes());
int res = posix.unlink(tmp.getCanonicalPath());
assertEquals(0, res);
assertFalse(tmp.exists());
raf.write("world".getBytes());
raf.seek(0);
byte[] actual = new byte[10];
raf.read(actual);
assertArrayEquals("helloworld".getBytes(), actual);
}
}
@Test
public void openTest() throws Throwable {
int fd = posix.open("pom.xml", 0, 0666);
assertNotEquals(-1, fd);
int result = posix.close(fd);
assertEquals(0, result);
result = posix.close(fd);
assertEquals(-1, result);
fd = posix.open("jnr-posix-filetest.txt", OpenFlags.O_CREAT.intValue() | OpenFlags.O_RDWR.intValue(), 0600);
assertEquals(0600, posix.stat("jnr-posix-filetest.txt").mode() & 0777);
result = posix.close(fd);
assertEquals(0, result);
new File("jnr-posix-filetest.txt").delete();
}
@Test
public void writeTest() throws Throwable {
String str = "To thine own self be true";
File tmp = File.createTempFile("writeTest", "tmp");
ByteBuffer buffer = ByteBuffer.wrap(str.getBytes());
int fd = posix.open(tmp.getAbsolutePath(), 1, 066);
posix.write(fd, buffer, str.length());
posix.close(fd);
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
assertEquals(raf.readLine(), new String(buffer.array()));
posix.unlink(tmp.getAbsolutePath());
}
@Test
public void pwriteTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
String str = "Now is the winter of our discontent";
File tmp = File.createTempFile("pwriteTest", "tmp");
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
raf.write(str.getBytes());
raf.close();
String str2 = "summer";
ByteBuffer buffer = ByteBuffer.wrap(str2.getBytes());
int fd = posix.open(tmp.getAbsolutePath(), 1, 066);
posix.pwrite(fd, buffer, str2.length(), 11);
posix.close(fd);
raf = new RandomAccessFile(tmp, "r");
assertEquals(raf.readLine(), "Now is the summer of our discontent");
posix.unlink(tmp.getAbsolutePath());
}
}
@Test
public void truncateTest() throws Throwable {
String str = "Beware the Jabberwock, my son!";
File tmp = File.createTempFile("truncateTest", "tmp");
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
raf.write(str.getBytes());
raf.close();
int shorterLength = str.length() - 10;
int longerLength = shorterLength * 2;
// Truncate should make a file shorter if the new length is less than the old length.
posix.truncate(tmp.getAbsolutePath(), shorterLength);
assertEquals(shorterLength, tmp.length());
// Truncate should extend a file if the new length is greater than the old length.
posix.truncate(tmp.getAbsolutePath(), longerLength);
assertEquals(longerLength, tmp.length());
}
@Test
public void ftruncateTest() throws Throwable {
String str = "Beware the Jabberwock, my son!";
File tmp = File.createTempFile("ftruncateTest", "tmp");
RandomAccessFile raf = new RandomAccessFile(tmp, "rw");
raf.write(str.getBytes());
raf.close();
int fd = posix.open(tmp.getAbsolutePath(), OpenFlags.O_RDWR.intValue(), 0666);
posix.ftruncate(fd, 21);
posix.lseekLong(fd, 0, 0);
byte[] buf = new byte[21];
int read = posix.read(fd, buf, 31);
assertEquals(21, read);
assertArrayEquals(buf, "Beware the Jabberwock".getBytes());
}
@Test
public void fcntlIntTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
int[] fds = new int[2];
int ret = posix.pipe(fds);
assertEquals(0, ret);
int flags = posix.fcntlInt(fds[0], Fcntl.F_GETFD, 0);
posix.fcntlInt(fds[0], Fcntl.F_SETFD, flags | 1); // FD_CLOEXEC
assertEquals(flags | 1, posix.fcntlInt(fds[0], Fcntl.F_GETFD, 0));
}
}
@Test
public void fchmodTest() throws IOException {
if (!Platform.IS_WINDOWS) {
File tmp = File.createTempFile("jnr-posix-chmod-test", "tmp");
int fd = posix.open(tmp.getAbsolutePath(), OpenFlags.O_RDWR.intValue(), 0600);
assertEquals("chmod: ", 0, posix.fchmod(fd, 0));
assertEquals("chmod: ", 0, posix.fchmod(fd, 0777));
tmp.delete();
}
}
@Test
public void renameTest() throws IOException {
File oldFile = File.createTempFile("jnr-posix-rename-test", "tmp");
File newFile = new File(oldFile.getParent() + File.separatorChar + "jnr-posix-rename-test-new");
assertTrue(oldFile.exists());
assertFalse(newFile.exists());
posix.rename(oldFile.getCanonicalPath(), newFile.getCanonicalPath());
assertFalse(oldFile.exists());
assertTrue(newFile.exists());
newFile.delete();
}
@Test
public void accessTest() throws IOException {
File tmp = File.createTempFile("jnr-posix-access-test", "tmp");
jnr.constants.platform.Access.F_OK.intValue();
// Set permissions to read-only and verify we don't have permissions to write.
String canonicalPath = tmp.getCanonicalPath();
assertEquals("chmod 0400: ", 0, posix.chmod(canonicalPath, 0400));
assertEquals("access " + canonicalPath + " for write: ", -1, posix.access(canonicalPath, Access.W_OK.intValue()));
assertEquals("access " + canonicalPath + " for read: ", 0, posix.access(canonicalPath, Access.R_OK.intValue()));
// Reset the permissions to read-write and verify we now have permissions to write.
assertEquals("chmod 0600: ", 0, posix.chmod(canonicalPath, 0600));
assertEquals("access " + canonicalPath + " for write: ", 0, posix.access(canonicalPath, Access.W_OK.intValue()));
assertEquals("access " + canonicalPath + " for read: ", 0, posix.access(canonicalPath, Access.R_OK.intValue()));
// F_OK just checks the file exists and should pass.
assertEquals("access " + canonicalPath + " exists: ", 0, posix.access(canonicalPath, Access.F_OK.intValue()));
}
@Test
public void readlinkTest() throws IOException {
if (!Platform.IS_WINDOWS) {
File file = File.createTempFile("jnr-pøsix-réådlînk-tést", "tmp");
File link = new File(file.getAbsolutePath() + "link");
posix.symlink(file.getAbsolutePath(), link.getAbsolutePath());
byte[] fileBytes = file.getAbsolutePath().getBytes();
int fileLength = fileBytes.length;
byte[] buffer = new byte[fileLength];
assertEquals(fileLength, posix.readlink(link.getAbsolutePath(), buffer, buffer.length));
assertArrayEquals(fileBytes, buffer);
link.delete();
file.delete();
}
}
@Test
public void readlinkByteBufferTest() throws IOException {
if (!Platform.IS_WINDOWS) {
File file = File.createTempFile("jnr-pøsix-réådlînk-tést", "tmp");
File link = new File(file.getAbsolutePath() + "link");
posix.symlink(file.getAbsolutePath(), link.getAbsolutePath());
byte[] fileBytes = file.getAbsolutePath().getBytes();
int fileLength = fileBytes.length;
ByteBuffer buffer = ByteBuffer.allocate(fileLength);
assertEquals(fileLength, posix.readlink(link.getAbsolutePath(), buffer, buffer.capacity()));
assertArrayEquals(buffer.array(), file.getAbsolutePath().getBytes());
link.delete();
file.delete();
}
}
@Test
public void readlinkPointerTest() throws IOException {
if (!Platform.IS_WINDOWS) {
File file = File.createTempFile("jnr-pøsix-réådlînk-tést", "tmp");
File link = new File(file.getAbsolutePath() + "link");
int bufSize = 1024;
Pointer buffer = jnr.ffi.Runtime.getSystemRuntime().getMemoryManager().allocateDirect(bufSize);
posix.symlink(file.getAbsolutePath(), link.getAbsolutePath());
byte[] fileBytes = file.getAbsolutePath().getBytes();
int fileLength = fileBytes.length;
assertEquals(fileLength, posix.readlink(link.getAbsolutePath(), buffer, bufSize));
assertEquals(file.getAbsolutePath(), buffer.getString(0, fileLength, Charset.defaultCharset()));
link.delete();
file.delete();
}
}
@Test
public void mkfifoTest() throws Throwable {
if (!Platform.IS_WINDOWS) {
File tmp = File.createTempFile("mkfifoTest", "tmp");
tmp.deleteOnExit();
int ret = posix.mkfifo(tmp.getAbsolutePath(), 0666);
FileInputStream fis = new FileInputStream(tmp);
FileOutputStream fos = new FileOutputStream(tmp);
byte[] content = "hello".getBytes();
fos.write(content);
fis.read(content);
assertArrayEquals("hello".getBytes(), content);
}
}
@Test
public void lseekTest() throws Throwable {
if (Platform.IS_MAC) {
int fd = posix.open("/dev/zero", 0, 0);
// use 2^33 to ensure we're out of int range
long offset = (long) Math.pow(2, 33);
long seek = posix.lseekLong(fd, offset, 0);
assertEquals(seek, offset);
}
}
private int getFdFromDescriptor(FileDescriptor descriptor) {
if (Platform.IS_WINDOWS) {
HANDLE handle = JavaLibCHelper.gethandle(descriptor);
return ((WindowsLibC) posix.libc())._open_osfhandle(handle, 0);
} else {
return JavaLibCHelper.getfdFromDescriptor(descriptor);
}
}
private FileDescriptor toDescriptor(int fd) {
if (Platform.IS_WINDOWS) {
HANDLE handle = ((WindowsLibC) posix.libc())._get_osfhandle(fd);
return JavaLibCHelper.toFileDescriptor(handle);
} else {
return JavaLibCHelper.toFileDescriptor(fd);
}
}
private boolean hasNanosecondPrecision(FileStat fileStat) {
return fileStat instanceof NanosecondFileStat && !Platform.IS_MAC;
}
private void utimensat(File file, int parentFd) {
String path = file.getAbsolutePath();
FileStat fileStat = posix.stat(path);
if (!hasNanosecondPrecision(fileStat)) {
file.delete();
return;
}
long atimeSeconds = fileStat.atime()+2;
long mtimeSeconds = fileStat.mtime()-2;
long atimeNanoSeconds = 123456789;
long mtimeNanoSeconds = 135;
posix.utimensat(parentFd,
path,
new long[] {atimeSeconds, atimeNanoSeconds},
new long[] {mtimeSeconds, mtimeNanoSeconds},
0);
assertStatNanoSecond(file, atimeSeconds, atimeNanoSeconds, mtimeSeconds, mtimeNanoSeconds);
}
private void assertStatNanoSecond(File file, long atimeSeconds, long atimeNanoSeconds, long mtimeSeconds, long mtimeNanoSeconds) {
NanosecondFileStat nanosecondFileStat = (NanosecondFileStat) posix.stat(file.getPath());
assertEquals("Access timestamp should be updated", atimeSeconds, nanosecondFileStat.atime());
assertEquals("Modification timestamp should be updated", mtimeSeconds, nanosecondFileStat.mtime());
assertEquals("Access time precision should be in ns", atimeNanoSeconds, nanosecondFileStat.aTimeNanoSecs());
assertEquals("Modification time precision should be in ns", mtimeNanoSeconds, nanosecondFileStat.mTimeNanoSecs());
file.delete();
}
}