code: private static String getRelativePath(File src, File target) {
          String[] srcComponents = getCanonicalPath(src).replace(File.separatorChar, '/').split("/");
          String[] targetComponents = getCanonicalPath(target).replace(File.separatorChar, '/').split("/");
  
          if (srcComponents.length > 0 && targetComponents.length > 0 && !targetComponents[0].equals(srcComponents[0])) {
              return null;
          }
  
          int common = 0;
          for (int minLength = Math.min(srcComponents.length, targetComponents.length); common < minLength; common++) {
              if (!srcComponents[common].equals(targetComponents[common])) {
                  break;
              }
          }
  
          StringBuilder result = new StringBuilder();
  
          // Paths in a file are relative to the file's directory, so subtract one
          // to skip the final filename component.
          for (int i = common; i < srcComponents.length - 1; i++) {
              if (result.length() != 0) {
                  result.append('/');
              }
              result.append("..");
          }
  
          for (int i = common; i < targetComponents.length; i++) {
              if (result.length() != 0) {
                  result.append('/');
              }
              result.append(targetComponents[i]);
          }
  
          return result.toString();
      }
docs: Return a relative path from the directory of the source file to the
  target file. If the target file is on a different drive (for example,
  "C:" vs "D:" on Windows), then there is no relative path, and null will
  be returned.