protected final TPipeTransferResp handleTransferFileSealV2(final PipeTransferFileSealReqV2 req) {
    final List<String> fileNames = req.getFileNames();
    final List<File> files =
        fileNames.stream()
            .map(
                fileName ->
                    Objects.nonNull(fileName)
                        ? new File(receiverFileDirWithIdSuffix.get(), fileName)
                        : null)
            .collect(Collectors.toList());
    try {
      if (!isWritingFileAvailable()) {
        final TSStatus status =
            RpcUtils.getStatus(
                TSStatusCode.PIPE_TRANSFER_FILE_ERROR,
                String.format(
                    "Failed to seal file %s, because writing file %s is not available.",
                    req.getFileNames(), writingFile));
        LOGGER.warn(status.getMessage());
        return new TPipeTransferResp(status);
      }

      // Any of the transferred files cannot be empty, or else the receiver
      // will not sense this file because no pieces are sent
      for (int i = 0; i < fileNames.size(); ++i) {
        final String fileName = fileNames.get(i);
        if (Objects.nonNull(fileName)) {
          final TPipeTransferResp resp =
              i == fileNames.size() - 1
                  ? checkFinalFileSeal(fileName, req.getFileLengths().get(i))
                  : checkNonFinalFileSeal(files.get(i), fileName, req.getFileLengths().get(i));
          if (Objects.nonNull(resp)) {
            return resp;
          }
        }
      }

      // Sync here is necessary to ensure that the data is written to the disk. Or data region may
      // load the file before the data is written to the disk and cause unexpected behavior after
      // system restart. (e.g., empty file in data region's data directory)
      if (PIPE_CONFIG.getPipeFileReceiverFsyncEnabled()) {
        writingFileWriter.getFD().sync();
      }
      // 1. The writing file writer must be closed, otherwise it may cause concurrent errors during
      // the process of loading tsfile when parsing tsfile.
      //
      // 2. The writing file must be set to null, otherwise if the next passed tsfile has the same
      // name as the current tsfile, it will bypass the judgment logic of
      // updateWritingFileIfNeeded#isFileExistedAndNameCorrect, and continue to write to the already
      // loaded file. Since the writing file writer has already been closed, it will throw a Stream
      // Close exception.
      writingFileWriter.close();
      writingFileWriter = null;

      // WritingFile will be deleted after load if no exception occurs
      writingFile = null;

      final List<String> fileAbsolutePaths =
          files.stream()
              .map(file -> Objects.nonNull(file) ? file.getAbsolutePath() : null)
              .collect(Collectors.toList());

      final TSStatus status = loadFileV2(req, fileAbsolutePaths);
      if (status.getCode() == TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
        LOGGER.info(
            "Receiver id = {}: Seal file {} successfully.", receiverId.get(), fileAbsolutePaths);
      } else {
        LOGGER.warn(
            "Receiver id = {}: Failed to seal file {}, status is {}.",
            receiverId.get(),
            fileAbsolutePaths,
            status);
      }
      return new TPipeTransferResp(status);
    } catch (final Exception e) {
      LOGGER.warn(
          "Receiver id = {}: Failed to seal file {} from req {}.", receiverId.get(), files, req, e);
      return new TPipeTransferResp(
          RpcUtils.getStatus(
              TSStatusCode.PIPE_TRANSFER_FILE_ERROR,
              String.format("Failed to seal file %s because %s", files, e.getMessage())));
    } finally {
      // If the writing file is not sealed successfully, the writing file will be deleted.
      // All pieces of the writing file and its mod(if exists) should be retransmitted by the
      // sender.
      closeCurrentWritingFileWriter(false);
      // Clear the directory instead of only deleting the referenced files in seal request
      // to avoid previously undeleted file being redundant when transferring multi files
      IoTDBReceiverAgent.cleanPipeReceiverDir(receiverFileDirWithIdSuffix.get());
    }
  }
{@link IoTDBFileReceiver} is the parent class of receiver on both configNode and DataNode,
handling all the logic of parallel file receiving.
iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/pipe/receiver/IoTDBFileReceiver.java