/**
   * 创建目录
   *
   * @param path 目录路径
   * @param auto 是否自动创建父级目录(最多10级)
   * @return true or false
   */
  public boolean mkDir(String path, boolean auto) {

    Map<String, String> params = new HashMap<String, String>(1);
    params.put(PARAMS.KEY_MAKE_DIR.getValue(), "true");

    String result = HttpAction(METHOD_PUT, formatPath(path), null, null, auto, params);

    return result != null;
  }
  /**
   * 连接处理逻辑
   *
   * @param method 请求方式 {GET, POST, PUT, DELETE}
   * @param uri 请求地址
   * @param datas 该请求所需发送数据(可为 null)
   * @param outFile 文件描述符(可为 null)
   * @param auto 自动创建父级目录(最多10级)
   * @param params 额外参数
   * @return 请求结果(字符串)或 null
   */
  private String HttpAction(
      String method,
      String uri,
      byte[] datas,
      File outFile,
      boolean auto,
      Map<String, String> params) {

    String result = null;

    HttpURLConnection conn = null;
    OutputStream os = null;
    InputStream is = null;

    try {
      // 获取链接
      URL url = new URL("http://" + apiDomain + uri);
      conn = (HttpURLConnection) url.openConnection();

      // 设置必要参数
      conn.setConnectTimeout(timeout);
      conn.setRequestMethod(method);
      conn.setUseCaches(false);
      conn.setDoOutput(true);

      // 设置时间
      conn.setRequestProperty(DATE, getGMTDate());

      // 是否自动创建父级目录
      if (auto) {
        conn.setRequestProperty(MKDIR, "true");
      }

      long contentLength = 0;
      if (datas == null) conn.setRequestProperty(CONTENT_LENGTH, "0");
      else {
        contentLength = datas.length;
        conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(datas.length));

        // 设置文件的 MD5 参数
        if (!isEmpty(this.contentMD5)) {
          conn.setRequestProperty(CONTENT_MD5, this.contentMD5);
          this.contentMD5 = null;
        }
        // 设置文件的访问密钥
        if (!isEmpty(this.fileSecret)) {
          conn.setRequestProperty(CONTENT_SECRET, this.fileSecret);
          this.fileSecret = null;
        }
      }

      // 设置签名
      conn.setRequestProperty(AUTHORIZATION, sign(conn, uri, contentLength));

      // 是否是创建文件目录
      boolean isFolder = false;

      // 设置额外的参数,如图片缩略图等
      if (params != null && !params.isEmpty()) {

        isFolder = !isEmpty(params.get(PARAMS.KEY_MAKE_DIR.getValue()));

        for (Map.Entry<String, String> param : params.entrySet()) {
          conn.setRequestProperty(param.getKey(), param.getValue());
        }
      }

      // 创建链接
      conn.connect();

      if (datas != null) {
        os = conn.getOutputStream();
        os.write(datas);
        os.flush();
      }

      if (isFolder) {
        os = conn.getOutputStream();
        os.flush();
      }

      if (outFile == null) {

        result = getText(conn, METHOD_HEAD.equals(method));

      } else {
        result = "";

        os = new FileOutputStream(outFile);
        byte[] data = new byte[4096];
        int temp = 0;

        is = conn.getInputStream();

        while ((temp = is.read(data)) != -1) {
          os.write(data, 0, temp);
        }
      }
    } catch (IOException e) {
      if (debug) e.printStackTrace();

      // 操作失败
      return null;

    } finally {

      try {
        if (os != null) {
          os.close();
          os = null;
        }
        if (is != null) {
          is.close();
          is = null;
        }
      } catch (IOException e) {
        e.printStackTrace();
      }

      if (conn != null) {
        conn.disconnect();
        conn = null;
      }
    }

    return result;
  }