在初始 运行 上从 React Native 项目文件夹中提取 zip 文件

Extract zip file from react native project folder on initial running

我们想在 React Native 项目中包含 zip 文件,例如在 project/src/assets/zip 文件夹中,将其包含在构建中并将其解压缩到本地 phone 存储在初始应用程序 运行 .

我们想要实现的是,假设我们有一个网页,我们想在 React Native 应用程序上显示。我们可以通过在项目中包含网页的资产来减少加载时间,然后告诉网页在本地搜索资产文件。

我们已成功显示包含从 Internet 下载的 zip 格式的本地资源的网页。但是我们还没有找到如何在本地项目上使用 zip 文件实现相同的目的。

我们已经尝试导入资产文件,然后像下面那样直接解压,但没有成功

import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'

...

componentDidMount() {
  const destination = RNFS.DocumentDirectoryPath + '/'
  unzip(zipFile, destination)
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })
}

我们已经尝试使用 react-native-local-resource 来获得具有多种组合的文件,但不幸的是

import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import loadLocalResource from 'react-native-local-resource'

...

componentDidMount() {
  const destination = RNFS.DocumentDirectoryPath + '/'
  loadLocalResource(assetsZip)
    .then((fileContent) => unzip(fileContent, destination))
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })
}

import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import loadLocalResource from 'react-native-local-resource'

...

componentDidMount() {
  const destination = RNFS.DocumentDirectoryPath + '/'
  const fileName = 'file.zip'
  loadLocalResource(assetsZip)
    .then((fileContent) => RNFS.writeFile(destination + fileName, fileContent))
    .then(() => unzip(destination + fileName, destination))
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })
}

我们如何将项目文件夹中的 zip 文件提取到 Phone 存储中?

编辑:

虽然之前的答案适用于应用程序的调试版本,但它似乎在生产中中断,因为在生产中 resource.uri return file:// uri 而不是 http:// 与调试版本一样。

要解决问题,我们需要检查它是 file uri 还是 http url。然后在 react-native-fs 上使用复制功能而不是下载功能,如果它是 file uri.

import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'

...

componentDidMount() {
  const destination = RNFS.DocumentDirectoryPath + '/'
  const filename = 'file.zip'

  const resource = resolveAssetSource(zipFile)
  const fileUri = resource.uri

  this.loadZipFile(fileUri, destination + filename)
    .then((result) => unzip(destination + filename, destination))
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })
  }
}

loadZipFile = (fileUri, destinationFile) = {
  if (fileUri.startWith('file://')) {
    return RNFS.copyFile(fileUri, destinationFile)
  } else {
    const downloadOptions = {
      fromUrl: fileUri,
      toFile: destinationFile
    }

    return RNFS.downloadFile(downloadOptions).promise
  }
}

这应该适用于生产和调试版本,即使使用代码推送发送 zip 文件在我们的案例中也能正常工作。

旧答案:

查看 react-native-local-resource 源代码后,我们想出了一些想法。

我们案例中 react-native-local-resource 的问题是,最终结果是 text,但 zip 文件不是 text。所以我们尝试拦截中间的代码来获取我们想要的zip文件。

经过一些实验,我们按照react-native-local-resource的代码得到文件的uri,然后使用react-native-fs将文件下载到本地存储文件夹,然后解压这些文件.

这是我们案例中的工作代码示例

import zipFile from './assets/zip/file.zip'
import * as RNFS from 'react-native-fs'
import { unzip } from 'react-native-zip-archive'
import resolveAssetSource from 'react-native/Libraries/Image/resolveAssetSource'

...

componentDidMount() {
  const destination = RNFS.DocumentDirectoryPath + '/'
  const filename = 'file.zip'

  const resource = resolveAssetSource(zipFile)
  const fileUri = resource.uri

  const downloadOptions = {
    fromUrl: fileUri,
    toFile: destination + filename
  }

  RNFS.downloadFile(downloadOptions).promise
    .then((result) => unzip(destination + filename, destination))
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })
}

希望对遇到同样问题的朋友有所帮助