如何使用react-native保存文件?

5lhxktic  于 2023-04-07  发布在  React
关注(0)|答案(5)|浏览(281)

我正在尝试下载并保存一个带有rn-fetch-blob的文件。(没有库我无法做到这一点,因为显然react-native只实现了浏览器的fetch接口的一个子集)。我的代码如下:

import RNFetchBlob from 'rn-fetch-blob'

RNFetchBlob
  .config({ path: RNFetchBlob.fs.dirs.DocumentDir + '/medias/foo' })
  .fetch('GET', 'http://example.com/files/foo', { 'Cache-Control': 'no-store' })
  .then(res => {
    console.log('file saved to ' + res.path())
  })

我得到了

[RNFetchBlobRequest] session didCompleteWithError (null)
[RNFetchBlobRequest] session didBecomeInvalidWithError (null)

Possible Unhandled Promise Rejection (id: 0):
Error: No such file '/Users/me/Library/Developer/CoreSimulator/Devices/0781956D-D2E6-4BC8-8943-62DA9B111BEF/data/Containers/Data/Application/A39E6A35-D248-4019-9CA0-1F9063E40161/Documents/medias/foo'
Error: No such file '/Users/me/Library/Developer/CoreSimulator/Devices/0781956D-D2E6-4BC8-8943-62DA9B111BEF/data/Containers/Data/Application/A39E6A35-D248-4019-9CA0-1F9063E40161/Documents/medias/foo'
    at createErrorFromErrorData (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1824:15)
    at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1777:25
    at MessageQueue.__invokeCallback (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:2135:16)
    at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1952:16
    at MessageQueue.__guard (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:2070:9)
    at MessageQueue.invokeCallbackAndReturnFlushedQueue (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1951:12)
    at http://localhost:8081/debugger-ui/debuggerWorker.js:72:58

未创建文件,(虚拟)设备中的“medias”目录仍为空。

如何使用react-native下载并保存文件?

6mw9ycah

6mw9ycah1#

试试这个。

import RNFetchBlob from 'rn-fetch-blob'
import Share from 'react-native-share'
import RNFS from 'react-native-fs'
import {Alert, Platform} from 'react-native'

const download = (url) => {
  let dirs = RNFetchBlob.fs.dirs
  try {
    if (Platform.OS === 'android') {
      const configOptions = { fileCache: true }
      RNFetchBlob.config(configOptions)
      .fetch('GET', url, {
      'Authorization': '', //yourTokenIfHave
      'Content-Type': '' // 'application/octet-stream'
    })
    .then(resp => {
      return resp.readFile('base64')
    })
    .then(async base64Data => {
      base64Data = `data:application/pdf;base64,` + base64Data
      await Share.open({ url: base64Data })
      // remove the image or pdf from device's storage
      await RNFS.unlink(filePath)
    })
} else {
  RNFetchBlob
    .config({
      fileCache: true,
      path: dirs.DocumentDir + `/${itemPDF.fileName}`
    })
    .fetch('GET', url, {
      'Authorization': '',
      'Content-Type': '' // 'application/octet-stream'
    })
    .then(async (res) => {

      // the temp file path
      if (res && res.path()) {
        const filePath = res.path()
        let options = {
          type: 'application/pdf',
          url: filePath
        }
        await Share.open(options)
        await RNFS.unlink(filePath)
      }
    })
    .catch((error) => {
      console.log(error)
    })
    }
  } catch (error) {
   console.log('download: ', error)
 }
}
11dmarpk

11dmarpk2#

我没有再次尝试rn-fetch-blob,我最终使用了react-native-fs,它工作正常。
(我在再次尝试保存文件之前进行了react-native版本升级,所以可能不完全是由于rn-fetch-blob中的错误,而是由于使用了旧的react-native版本。

rqenqsqc

rqenqsqc3#

您的问题似乎是访问该目录.config({ path: RNFetchBlob.fs.dirs.DocumentDir + '/medias/foo' })的权限,可能是因为/medias/foo不存在,请尝试在没有特定路径的情况下执行此操作。
我总是以这种方式使用它,如docs中所解释的:

RNFetchBlob
  .config({
    // add this option that makes response data to be stored as a file,
    // this is much more performant.
    fileCache : true,
  })
  .fetch('GET', 'http://www.example.com/file/example.zip', {
    //some headers ..
  })
  .then((res) => {
    // the temp file path
    console.log('The file saved to ', res.path())
  })
2uluyalo

2uluyalo4#

我也遇到了同样的问题,如果你使用的是“rn-fetch-blob”:0.10.14切换到“0.10.13”,检查https://github.com/joltup/rn-fetch-blob/issues/266 & https://github.com/wonday/react-native-pdf/issues/286

cwdobuhd

cwdobuhd5#

这是一个下载文件并将其保存到适当文件路径的示例函数。请记住,这是一个通用函数,因此请根据您的用例调整它。

const downloadFile = ({
  fileExt
}) => {
  ReactNativeBlobUtil.config({
      fileCache: true,
    }).fetch('GET', filePath)
    .then(async(res) => {
      ToastAndroid.show('Download Successful', ToastAndroid.SHORT);
      // in iOS, we want to save our files by opening up the saveToFiles bottom sheet action.
      // whereas in android, the download manager is handling the download for us.
      if (Platform.OS === 'ios') {
        ReactNativeBlobUtil.ios.openDocument(res.data);
      } else {
        await ReactNativeBlobUtil.MediaCollection.copyToMediaStore({
            name: fileName,
            parentFolder: `${ParentFolder}/${fileExt.toUpperCase()}`, // it will store the file in this path
            mimeType: fileType
          },
          'Download', // Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download")
          res.path());
      }
    })
    .catch((err) => console.log('BLOB ERROR -> ', err));
}

请记住,复制到媒体存储是最重要的部分。您也可以在下载前向用户询问存储权限。

相关问题