@Override
  public TableMetadata refresh() {
    int ver = version != null ? version : findVersion();
    try {
      Path metadataFile = getMetadataFile(ver);
      if (version == null && metadataFile == null && ver == 0) {
        // no v0 metadata means the table doesn't exist yet
        return null;
      } else if (metadataFile == null) {
        throw new ValidationException("Metadata file for version %d is missing", ver);
      }

      Path nextMetadataFile = getMetadataFile(ver + 1);
      while (nextMetadataFile != null) {
        ver += 1;
        metadataFile = nextMetadataFile;
        nextMetadataFile = getMetadataFile(ver + 1);
      }

      updateVersionAndMetadata(ver, metadataFile.toString());

      this.shouldRefresh = false;
      return currentMetadata;
    } catch (IOException e) {
      throw new RuntimeIOException(e, "Failed to refresh the table");
    }
  }
TableOperations implementation for file systems.

<p>For normal file-system(support atomic non-overwriting rename). Users can use it directly
without configuring additional lockManager.

<p>For object storage(not support atomic non-overwriting rename), user should choose a suitable
lockManager implementation.

<p>This maintains metadata in a "metadata" folder under the table location.
iceberg/patched-iceberg-core/src/main/java/org/apache/iceberg/hadoop/HadoopTableOperations.java