You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从React Native WebView向React Native流式传输数据以保存大文件?

React Native WebView 流式传输大文件到本地磁盘方案

针对大文件从WebView传输到React Native并保存到磁盘的需求,你可以采用以下两种高效方案:

方案1:分块传输Base64数据(无需额外Native模块)

将大文件切割成固定大小的块,分批通过postMessage发送,Native端逐块写入文件流,最后完成保存。

WebView端代码

async function splitAndSendFile(file) {
  const chunkSize = 1024 * 1024; // 按1MB分块,可根据需求调整
  let offset = 0;
  const fileReader = new FileReader();

  while (offset < file.size) {
    const chunk = file.slice(offset, offset + chunkSize);
    await new Promise(resolve => {
      fileReader.onload = (e) => {
        // 剔除Base64前缀,只保留编码内容
        const base64Chunk = e.target.result.split(',')[1];
        window.ReactNativeWebView.postMessage(JSON.stringify({
          type: 'fileChunk',
          data: base64Chunk,
          fileName: file.name,
          chunkOffset: offset,
          totalSize: file.size
        }));
        resolve();
      };
      fileReader.readAsDataURL(chunk);
    });
    offset += chunkSize;
  }

  // 发送传输完成信号
  window.ReactNativeWebView.postMessage(JSON.stringify({
    type: 'fileComplete',
    fileName: file.name
  }));
}

React Native端代码

需要依赖react-native-fs库处理文件写入:

import RNFS from 'react-native-fs';

let fileWriteStream = null;
let activeFilePath = '';

const handleWebViewMessage = (event) => {
  const msg = JSON.parse(event.nativeEvent.data);
  switch (msg.type) {
    case 'fileChunk':
      if (!fileWriteStream) {
        // 初始化文件路径
        activeFilePath = `${RNFS.DocumentDirectoryPath}/${msg.fileName}`;
        // 创建写入流,逐块追加
        fileWriteStream = RNFS.appendFile(activeFilePath, msg.data, 'base64');
      } else {
        fileWriteStream = fileWriteStream.then(() => 
          RNFS.appendFile(activeFilePath, msg.data, 'base64')
        );
      }
      break;
    case 'fileComplete':
      fileWriteStream?.then(() => {
        console.log('文件保存完成:', activeFilePath);
        fileWriteStream = null;
      }).catch(err => {
        console.error('文件保存失败:', err);
        // 清理未完成文件
        RNFS.unlink(activeFilePath);
      });
      break;
  }
};

// 在WebView组件中绑定消息监听
<WebView
  source={{ uri: '你的网页地址' }}
  onMessage={handleWebViewMessage}
/>

方案2:自定义Native通信桥(性能更优)

跳过Base64编码,直接传递二进制数据,减少编码开销,适合超大型文件:

  • 在React Native中实现自定义Native模块,暴露writeFileChunk方法,接收二进制数据和文件信息
  • WebView端读取文件的ArrayBuffer,分块调用Native模块的方法传递原始二进制数据
  • Native端直接将二进制数据写入文件流,避免Base64转码的性能损耗

核心思路示例

WebView端:

async function streamFileToNative(file) {
  const chunkSize = 2 * 1024 * 1024; // 2MB分块
  let offset = 0;
  const fileReader = new FileReader();

  while (offset < file.size) {
    const chunk = file.slice(offset, offset + chunkSize);
    await new Promise(resolve => {
      fileReader.onload = (e) => {
        // 调用自定义Native模块方法传递二进制数据
        window.NativeModules.FileWriter.writeChunk(
          file.name,
          new Uint8Array(e.target.result),
          offset,
          file.size
        );
        resolve();
      };
      fileReader.readAsArrayBuffer(chunk);
    });
    offset += chunkSize;
  }
  window.NativeModules.FileWriter.finishFileWrite(file.name);
}

关键注意事项

  • 分块大小需平衡:过小会增加通信次数,过大可能导致内存占用过高或postMessage超时
  • 需处理传输中断场景:WebView页面关闭时,Native端要清理未完成的临时文件
  • 可添加进度同步:WebView端计算已传输比例,通过postMessage发送给Native更新UI进度条

内容的提问来源于stack exchange,提问作者user5507535

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 05:31:39