下载文件的功能

使用第三方库react-native-fs
代码如下:

import RNFS from "react-native-fs";
import { I18n } from "../lang";
import { Tools } from "../utils";
import { Platform } from "react-native";

/**
 * 下载文件
 * 
 * 测试代码:
 * const res = await downloadBusiness.downloadDocument({
                 fileUrl: "https://github.com/goweii/TestUrl/raw/master/AndroidKeyMd5.pdf",
                 fileName: "contract.pdf",
               });
 
               if (res.success) {
                 console.log(res.filePath);
                 Tools.info("文件下载成功,路径:" + res.filePath)
               }
 * 
 */
class DownloadBusiness {
  normalizeUrl = (url) => {
    if (Tools.isEmptyStr(url)) {
      return "";
    }
    try {
      return encodeURI(String(url).trim());
    } catch (error) {
      return String(url).trim();
    }
  }

  getFileExt = (fileUrl, defaultExt = "pdf") => {
    try {
      const pureUrl = String(fileUrl ?? "").split("?")[0];
      const ext = pureUrl.substring(pureUrl.lastIndexOf(".") + 1).trim();
      if (!ext || ext.includes("/") || ext.length > 10) {
        return defaultExt;
      }
      return ext;
    } catch (error) {
      return defaultExt;
    }
  }

  sanitizeFileName = (fileName) => {
    if (Tools.isEmptyStr(fileName)) {
      return "";
    }
    const cleanName = String(fileName).replace(/[\\/:*?"<>|]/g, "_").trim();
    return cleanName;
  }

  getFileName = (fileUrl, fileName, defaultExt = "pdf") => {
    const ext = this.getFileExt(fileUrl, defaultExt);

    let finalName = this.sanitizeFileName(fileName);
    if (Tools.isEmptyStr(finalName)) {
      const pureUrl = String(fileUrl ?? "").split("?")[0];
      const urlLast = pureUrl.split("/").pop();

      let decodedName = urlLast ?? "";
      try {
        decodedName = decodeURIComponent(decodedName);
      } catch (error) {
      }
      finalName = this.sanitizeFileName(decodedName);
    }

    if (Tools.isEmptyStr(finalName)) {
      finalName = `document_${Date.now()}.${ext}`;
    } else if (!finalName.includes(".")) {
      finalName = `${finalName}.${ext}`;
    }

    return finalName;
  }

  getDownloadDir = async () => {
    let dir = "";
    if (Platform.OS == "ios") {
      dir = `${RNFS.DocumentDirectoryPath}/downloads`;
    } else {
      dir =  `${RNFS.ExternalDirectoryPath}/downloads`;
    }
    const exists = await RNFS.exists(dir);
    if (!exists) {
      await RNFS.mkdir(dir);
    }
    return dir;
  }

  removeFileIfExists = async (filePath) => {
    const exists = await RNFS.exists(filePath);
    if (exists) {
      await RNFS.unlink(filePath);
    }
  }

  /**
   * 下载文档到应用本地目录
   * @param {{fileUrl: string, fileName?: string, defaultExt?: string, headers?: object, showLoading?: boolean, showToast?: boolean}} params
   * @returns {Promise<{success: boolean, filePath?: string, fileName?: string, statusCode?: number, error?: any}>}
   */
  downloadDocument = async (params = {}) => {
    const {
      fileUrl,
      fileName,
      defaultExt = "pdf",
      headers = {},
      showLoading = true,
      showToast = true,
    } = params;

    if (Tools.isEmptyStr(fileUrl)) {
      if (showToast) {
        Tools.info(I18n.t("my.failed"));
      }
      return { success: false, error: "fileUrl is empty" };
    }

    if (showLoading) {
      Tools.showDarktLoading();
    }

    try {
      const requestUrl = this.normalizeUrl(fileUrl);
      const finalName = this.getFileName(requestUrl, fileName, defaultExt);
      const dir = await this.getDownloadDir();
      const toFile = `${dir}/${finalName}`;

      await this.removeFileIfExists(toFile);

      const result = await RNFS.downloadFile({
        fromUrl: requestUrl,
        toFile,
        headers,
      }).promise;

      if (result.statusCode >= 200 && result.statusCode < 300) {

        if (showToast) {
          Tools.info(I18n.t("my.success"));
        }
        return {
          success: true,
          filePath: toFile,
          fileName: finalName,
          statusCode: result.statusCode,
        };
      }

      await this.removeFileIfExists(toFile);

      if (showToast) {
        Tools.info(I18n.t("my.saveFailed"));
      }
      return {
        success: false,
        statusCode: result.statusCode,
        error: `download failed with status code ${result.statusCode}`,
      };
    } catch (error) {
      console.log("====== DownloadBusiness.downloadDocument error ======", error);
      if (showToast) {
        Tools.info(I18n.t("my.saveFailed"));
      }
      return {
        success: false,
        error,
      };
    } finally {
      if (showLoading) {
        Tools.hideDarkLoading();
      }
    }
  }
}

const downloadBusiness = new DownloadBusiness();
export default downloadBusiness;

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容