public static void main(String[] args) throws IOException {
    if (!checkArgs(args)) {
      System.exit(1);
    }
    if (printToFile) {
      pw = new PrintWriter(new FileWriter(outFilePath));
      validationScan.setPrintWriter(pw);
    }
    if (printDetails) {
      printBoth("Start checking seq files ...");
      validationScan.setPrintDetails(printDetails);
    }
    validationScan.setIgnoreFileOverlap(ignoreFileOverlap);

    // check tsfile
    for (File f : fileList) {
      findIncorrectFiles(Collections.singletonList(f));
    }

    // check tsfiles in data dir, which will check for correctness inside one single tsfile and
    // between files
    for (File seqDataDir : seqDataDirList) {
      // get sg data dirs
      if (!checkIsDirectory(seqDataDir)) {
        continue;
      }
      List<File> rootTsFiles =
          Arrays.asList(
              Objects.requireNonNull(
                  seqDataDir.listFiles(file -> file.getName().endsWith(TSFILE_SUFFIX))));
      findIncorrectFiles(rootTsFiles);

      List<File> sgDirs =
          Arrays.asList(Objects.requireNonNull(seqDataDir.listFiles(File::isDirectory)));
      for (File sgDir : Objects.requireNonNull(sgDirs)) {
        if (!checkIsDirectory(sgDir)) {
          continue;
        }
        if (printDetails) {
          printBoth("- Check files in database: " + sgDir.getAbsolutePath());
        }
        // get data region dirs
        File[] dataRegionDirs = sgDir.listFiles();
        for (File dataRegionDir : Objects.requireNonNull(dataRegionDirs)) {
          if (!checkIsDirectory(dataRegionDir)) {
            continue;
          }
          // get time partition dirs and sort them
          List<File> timePartitionDirs =
              Arrays.asList(Objects.requireNonNull(dataRegionDir.listFiles())).stream()
                  .filter(file -> Pattern.compile("[0-9]*").matcher(file.getName()).matches())
                  .collect(Collectors.toList());
          timePartitionDirs.sort(
              (f1, f2) ->
                  Long.compareUnsigned(Long.parseLong(f1.getName()), Long.parseLong(f2.getName())));
          for (File timePartitionDir : Objects.requireNonNull(timePartitionDirs)) {
            if (!checkIsDirectory(timePartitionDir)) {
              continue;
            }
            // get all seq files under the time partition dir
            List<File> tsFiles =
                Arrays.asList(
                    Objects.requireNonNull(
                        timePartitionDir.listFiles(
                            file -> file.getName().endsWith(TSFILE_SUFFIX))));
            // sort the seq files with timestamp
            tsFiles.sort(
                (f1, f2) -> {
                  int timeDiff =
                      Long.compareUnsigned(
                          Long.parseLong(f1.getName().split("-")[0]),
                          Long.parseLong(f2.getName().split("-")[0]));
                  return timeDiff == 0
                      ? Long.compareUnsigned(
                          Long.parseLong(f1.getName().split("-")[1]),
                          Long.parseLong(f2.getName().split("-")[1]))
                      : timeDiff;
                });

            findIncorrectFiles(tsFiles);
          }
          // clear map
          clearMap(false);
        }
      }
    }
    if (printDetails) {
      printBoth("Finish checking successfully, totally find " + getBadFileNum() + " bad files.");
    }
    if (printToFile) {
      pw.close();
    }
  }
The form of param is: [path of data dir or tsfile] [-pd = print details or not] [-f = path of
outFile]. Eg: xxx/iotdb/data/data1 xxx/xxx.tsfile -pd=true -f=xxx/TsFile_validation_view.txt

<p>The first parameter is required, the others are optional.
iotdb-core/datanode/src/main/java/org/apache/iotdb/db/tools/validate/TsFileValidationTool.java