public DownloadFileResult downloadFile(DownloadFileRequest downloadFileRequest) throws Throwable {
    assertParameterNotNull(downloadFileRequest, "downloadFileRequest");

    String bucketName = downloadFileRequest.getBucketName();
    String key = downloadFileRequest.getKey();

    assertParameterNotNull(bucketName, "bucketName");
    assertParameterNotNull(key, "key");
    ensureBucketNameValid(bucketName);
    ensureObjectKeyValid(key);

    // 没有指定本地文件,使用key作为本地文件名称
    if (downloadFileRequest.getDownloadFile() == null) {
      downloadFileRequest.setDownloadFile(downloadFileRequest.getKey());
    }

    // 开启断点续传,没有指定checkpoint文件,使用默认值
    if (downloadFileRequest.isEnableCheckpoint()) {
      if (downloadFileRequest.getCheckpointFile() == null
          || downloadFileRequest.getCheckpointFile().isEmpty()) {
        downloadFileRequest.setCheckpointFile(downloadFileRequest.getDownloadFile() + ".dcp");
      }
    }

    return downloadFileWithCheckpoint(downloadFileRequest);
  }
  private void prepare(
      DownloadCheckPoint downloadCheckPoint, DownloadFileRequest downloadFileRequest)
      throws IOException {
    downloadCheckPoint.magic = DownloadCheckPoint.DOWNLOAD_MAGIC;
    downloadCheckPoint.downloadFile = downloadFileRequest.getDownloadFile();
    downloadCheckPoint.bucketName = downloadFileRequest.getBucketName();
    downloadCheckPoint.objectKey = downloadFileRequest.getKey();
    downloadCheckPoint.objectStat =
        ObjectStat.getFileStat(
            objectOperation, downloadCheckPoint.bucketName, downloadCheckPoint.objectKey);
    downloadCheckPoint.downloadParts =
        splitFile(downloadCheckPoint.objectStat.size, downloadFileRequest.getPartSize());

    createFixedFile(downloadFileRequest.getDownloadFile(), downloadCheckPoint.objectStat.size);
  }