You need to enable JavaScript to run this app. React Native如何实现设备内.pdf/.doc等多格式文档的检索功能
优惠活动
大模型
产品
解决方案
定价
更多

React Native如何实现设备内.pdf/.doc等多格式文档的检索功能

React Native 多格式文档检索实现方案

第一步:权限配置

Android端权限

  • Android 13及以上:需要申请READ_MEDIA_IMAGES等媒体权限,如需扫描整个设备存储,还需要引导用户手动开启「所有文件访问」特殊权限
  • Android 12及以下:申请READ_EXTERNAL_STORAGE、WRITE_EXTERNAL_STORAGE权限
    所有权限除了在AndroidManifest.xml中声明,还需要做动态申请。

iOS端权限

需要在Info.plist中添加NSDocumentFolderUsageDescription、NSLibrariesFolderUsageDescription权限说明,明确告知用户访问文件的用途。

第二步:核心实现逻辑

你之前使用的lstat仅能获取当前目录的一级文件/文件夹信息,要检索全设备文档需要做递归目录遍历,Android端也可以调用MediaStore实现更高效率的查询,以下是跨平台的递归遍历实现代码:

import { PermissionsAndroid, Platform } from 'react-native';
import RNFetchBlob from 'rn-fetch-blob';

// 允许匹配的文档后缀
const ALLOWED_EXTENSIONS = ['pdf', 'doc', 'docx', 'ppt', 'pptx', 'xls', 'xlsx', 'txt'];

// 动态申请存储权限
const requestStoragePermission = async () => {
  if (Platform.OS !== 'android') return true;
  if (Platform.Version >= 33) {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.READ_MEDIA_IMAGES,
      {
        title: '存储访问权限',
        message: '需要访问设备存储以查找文档',
        buttonPositive: '允许',
      }
    );
    return granted === PermissionsAndroid.RESULTS.GRANTED;
  } else {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.READ_EXTERNAL_STORAGE,
      {
        title: '存储访问权限',
        message: '需要访问设备存储以查找文档',
        buttonPositive: '允许',
      }
    );
    return granted === PermissionsAndroid.RESULTS.GRANTED;
  }
};

// 递归遍历目录筛选符合条件的文件
const scanDirectory = async (dirPath, resultList = []) => {
  try {
    const stats = await RNFetchBlob.fs.lstat(dirPath);
    for (const item of stats) {
      // 跳过系统目录、隐藏目录,避免无权限报错
      if (item.type === 'directory' && !item.path.includes('/Android/') && !item.path.startsWith('.')) {
        await scanDirectory(item.path, resultList);
      } else if (item.type === 'file') {
        const fileExtension = item.filename.split('.').pop().toLowerCase();
        if (ALLOWED_EXTENSIONS.includes(fileExtension)) {
          resultList.push({
            name: item.filename,
            path: item.path,
            size: item.size,
            lastModified: item.lastModified,
            type: fileExtension
          });
        }
      }
    }
    return resultList;
  } catch (err) {
    // 跳过无权限访问的目录不报错
    return resultList;
  }
};

// 业务调用示例
useEffect(() => {
  const getDocuments = async () => {
    const hasPermission = await requestStoragePermission();
    if (!hasPermission) return;
    const rootDir = RNFetchBlob.fs.dirs.SDCardDir;
    const documents = await scanDirectory(rootDir);
    console.log('检索到的文档列表:', documents);
  };
  getDocuments();
}, []);

性能优化建议

  • Android端如果需要更高的扫描效率,建议自行封装原生模块调用MediaStore接口,通过SQL语句直接筛选指定后缀的文件,查询速度比递归遍历高10倍以上
  • iOS端如果不需要后台自动扫描,也可以调用系统文档选择器让用户主动选择目标文档,不需要申请全存储访问权限

内容的提问来源于stack exchange,提问作者Engr.Aftab Ufaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 10:24:03