private void scanKeysValues(Path file, KeyValueStatsCollector fileStats, HFileScanner scanner,
    byte[] row) throws IOException {
    Cell pCell = null;
    FileSystem fs = FileSystem.get(getConf());
    Set<String> foundMobFiles = new LinkedHashSet<>(FOUND_MOB_FILES_CACHE_CAPACITY);
    Set<String> missingMobFiles = new LinkedHashSet<>(MISSING_MOB_FILES_CACHE_CAPACITY);
    do {
      ExtendedCell cell = scanner.getCell();
      if (row != null && row.length != 0) {
        int result = CellComparator.getInstance().compareRows(cell, row, 0, row.length);
        if (result > 0) {
          break;
        } else if (result < 0) {
          continue;
        }
      }
      // collect stats
      if (printStats) {
        fileStats.collect(cell, printStatRanges);
      }
      // dump key value
      if (printKey) {
        out.print("K: " + cell);
        if (printValue) {
          out.print(" V: " + Bytes.toStringBinary(cell.getValueArray(), cell.getValueOffset(),
            cell.getValueLength()));
          int i = 0;
          List<Tag> tags = PrivateCellUtil.getTags(cell);
          for (Tag tag : tags) {
            out.print(String.format(" T[%d]: %s", i++, tag.toString()));
          }
        }
        out.println();
      }
      // check if rows are in order
      if (checkRow && pCell != null) {
        if (CellComparator.getInstance().compareRows(pCell, cell) > 0) {
          err.println("WARNING, previous row is greater then" + " current row\n\tfilename -> "
            + file + "\n\tprevious -> " + CellUtil.getCellKeyAsString(pCell) + "\n\tcurrent  -> "
            + CellUtil.getCellKeyAsString(cell));
        }
      }
      // check if families are consistent
      if (checkFamily) {
        String fam =
          Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength());
        if (!file.toString().contains(fam)) {
          err.println("WARNING, filename does not match kv family," + "\n\tfilename -> " + file
            + "\n\tkeyvalue -> " + CellUtil.getCellKeyAsString(cell));
        }
        if (pCell != null && CellComparator.getInstance().compareFamilies(pCell, cell) != 0) {
          err.println(
            "WARNING, previous kv has different family" + " compared to current key\n\tfilename -> "
              + file + "\n\tprevious -> " + CellUtil.getCellKeyAsString(pCell) + "\n\tcurrent  -> "
              + CellUtil.getCellKeyAsString(cell));
        }
      }
      // check if mob files are missing.
      if (checkMobIntegrity && MobUtils.isMobReferenceCell(cell)) {
        Optional<TableName> tn = MobUtils.getTableName(cell);
        if (!tn.isPresent()) {
          System.err.println(
            "ERROR, wrong tag format in mob reference cell " + CellUtil.getCellKeyAsString(cell));
        } else if (!MobUtils.hasValidMobRefCellValue(cell)) {
          System.err.println(
            "ERROR, wrong value format in mob reference cell " + CellUtil.getCellKeyAsString(cell));
        } else {
          String mobFileName = MobUtils.getMobFileName(cell);
          boolean exist = mobFileExists(fs, tn.get(), mobFileName,
            Bytes.toString(CellUtil.cloneFamily(cell)), foundMobFiles, missingMobFiles);
          if (!exist) {
            // report error
            System.err.println("ERROR, the mob file [" + mobFileName
              + "] is missing referenced by cell " + CellUtil.getCellKeyAsString(cell));
          }
        }
      }
      pCell = cell;
      ++count;
    } while (scanner.next());
  }
Runs the command-line pretty-printer, and returns the desired command exit code (zero for
success, non-zero for failure).
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFilePrettyPrinter.java