@Override
 public UnixFileAttributes readAttributes() throws IOException {
   checkReadExtended();
   try {
     return UnixFileAttributes.get(file, followLinks);
   } catch (UnixException x) {
     x.rethrowAsIOException(file);
     return null; // keep compiler happy
   }
 }
    @Override
    public void setTimes(FileTime lastModifiedTime, FileTime lastAccessTime, FileTime createTime)
        throws IOException {
      // null => don't change
      if (lastModifiedTime == null && lastAccessTime == null) {
        // no effect
        return;
      }

      // permission check
      file.checkWrite();

      int fd = file.openForAttributeAccess(followLinks);
      try {
        // if not changing both attributes then need existing attributes
        if (lastModifiedTime == null || lastAccessTime == null) {
          try {
            UnixFileAttributes attrs = UnixFileAttributes.get(fd);
            if (lastModifiedTime == null) lastModifiedTime = attrs.lastModifiedTime();
            if (lastAccessTime == null) lastAccessTime = attrs.lastAccessTime();
          } catch (UnixException x) {
            x.rethrowAsIOException(file);
          }
        }

        // uptime times
        long modValue = lastModifiedTime.to(TimeUnit.MICROSECONDS);
        long accessValue = lastAccessTime.to(TimeUnit.MICROSECONDS);

        boolean retry = false;
        try {
          futimes(fd, accessValue, modValue);
        } catch (UnixException x) {
          // if futimes fails with EINVAL and one/both of the times is
          // negative then we adjust the value to the epoch and retry.
          if (x.errno() == UnixConstants.EINVAL && (modValue < 0L || accessValue < 0L)) {
            retry = true;
          } else {
            x.rethrowAsIOException(file);
          }
        }
        if (retry) {
          if (modValue < 0L) modValue = 0L;
          if (accessValue < 0L) accessValue = 0L;
          try {
            futimes(fd, accessValue, modValue);
          } catch (UnixException x) {
            x.rethrowAsIOException(file);
          }
        }
      } finally {
        close(fd);
      }
    }
 @Override
 public BasicFileAttributes readAttributes() throws IOException {
   file.checkRead();
   try {
     UnixFileAttributes attrs = UnixFileAttributes.get(file, followLinks);
     return attrs.asBasicFileAttributes();
   } catch (UnixException x) {
     x.rethrowAsIOException(file);
     return null; // keep compiler happy
   }
 }
  @Override
  public UserPrincipal getOwner() throws IOException {
    checkAccess(file, true, false);

    try {
      UnixFileAttributes attrs = UnixFileAttributes.get(file, followLinks);
      return UnixUserPrincipals.fromUid(attrs.uid());
    } catch (UnixException x) {
      x.rethrowAsIOException(file);
      return null; // keep compile happy
    }
  }