code: public static void copyFile(FileSystem srcFs, Path src, FileSystem dstFs, Path dst, Path tmp, boolean overwriteDst,
        Configuration conf) throws IOException {
  
      Preconditions.checkArgument(srcFs.isFile(src),
          String.format("Cannot copy from %s to %s because src is not a file", src, dst));
  
      if (FS_SCHEMES_NON_ATOMIC.contains(srcFs.getUri().getScheme())
          || FS_SCHEMES_NON_ATOMIC.contains(dstFs.getUri().getScheme())) {
        copyFile(srcFs, src, dstFs, dst, overwriteDst, conf);
      } else {
        copyFile(srcFs, src, dstFs, tmp, overwriteDst, conf);
        try {
          boolean renamed = false;
          if (overwriteDst && dstFs.exists(dst)) {
            try {
              deletePath(dstFs, dst, true);
            } finally {
              renamePath(dstFs, tmp, dst);
              renamed = true;
            }
          }
          if (!renamed) {
            renamePath(dstFs, tmp, dst);
          }
        } finally {
          deletePath(dstFs, tmp, true);
        }
      }
    }
docs: Copies a src {@link Path} from a srcFs {@link FileSystem} to a dst {@link Path} on a dstFs {@link FileSystem}. If
  either the srcFs or dstFs are S3 {@link FileSystem}s (as dictated by {@link #FS_SCHEMES_NON_ATOMIC}) then data is directly
  copied from the src to the dst. Otherwise data is first copied to a tmp {@link Path}, which is then renamed to the
  dst.
  
  @param srcFs the source {@link FileSystem} where the src {@link Path} exists
  @param src the {@link Path} to copy from the source {@link FileSystem}
  @param dstFs the destination {@link FileSystem} where the dst {@link Path} should be created
  @param dst the {@link Path} to copy data to
  @param tmp the temporary {@link Path} to use when copying data
  @param overwriteDst true if the destination and tmp path should should be overwritten, false otherwise