react-native-fs:如何读取本地图像(获取本地文件的base64)

时间:2019-02-07 16:48:03

标签: react-native react-native-fs

我的应用程序中有本地文件,其内容如下:

<Image source={require("../../img/pic1.jpg") />

如何使用RNFS.readFile(filepath, "base64");读取此文件 使用RNFS.readFile("../../img/pic1.jpg", "base64");会给我错误“没有这样的文件”

2 个答案:

答案 0 :(得分:5)

react-native-fs将仅访问设备存储中的文件。因此,这个问题引起了困惑。这些文件在构建时捆绑在一起,那么我们如何在开发和生产中访问它们?

我的项目结构

├── android
├── app
│   └── assets
│       └── images
└── ios

我将图像存储在./app/assets/images/

发展

开发调试中,文件通过Metro捆绑器提供给设备,因此它们实际上并未存储在设备上。因此将无法从设备存储访问它们。开发时,您必须提供某种 mocked 功能。可以根据环境https://facebook.github.io/react-native/docs/javascript-environment使用__DEV__来允许运行不同的功能

if (__DEV__) {
  // do something in development
} else {
  // do something in production
}

生产

从一些研究看来,似乎可以访问生产环境中的文件。

iOS

我发现,这些文件位于assets中名为MainBundlePath的文件夹中。

因此,如果要访问我的本地目录./app/assets/images/image.png中的以下文件,则需要以下文件路径:RNFS.MainBundlePath + /assets/app/assets/images/image.png才能在设备上访问它。

您可以通过查看Packaging.log生成的ipa来查看文件路径。

Android

Android没有仅位于MainBundlePath上的名为iOS的文件夹。我花了一些时间研究和查看设备上的不同文件夹,但无法访问捆绑的图像。似乎无法像我们希望使用react-native-fs那样访问它们。

可能的解决方案

rn-fetch-blob

rn-fetch-blob具有iosAndroid的功能,可从资产目录读取

要访问iOS的文件,您需要执行以下操作:

RNFetchBlob.fs.stat(fs.dirs.MainBundleDir + '/whatever/files/you/added.mp3').then( stats => {...});

对于Android,您将执行以下操作:

RNFetchBlob.fs.stat(fs.asset('/whatever/files/you/added.mp3').then( stats => {...});

它确实发出有关Gradle正在压缩资产的警告。

  

默认情况下,Gradle将压缩捆绑资产。为了使用此模块与资产文件交互,必须禁用压缩。有关更多详细信息,请参见How to access files from assets

这可以解释为什么我在使用react-native-fs时无法在Android中找到任何资产

您可以在https://github.com/joltup/rn-fetch-blob#user-content-file-system

上阅读有关使用rn-fetch-blob及其文件系统的更多信息。

将文件存储在本机项目中

而不是依靠捆绑器为您打包图像并将其放在设备上。您可以将它们的副本存储在iOSAndroid项目中。这具有图像可以在开发中使用的好处,但是您将图像存储多次,这可能会导致更大的应用程序大小。

将图像存储为base64

您可以将图像作为base64字符串存储在json文件中,然后由您的应用程序要求。这将意味着您已经在base64中拥有了它们(因此该应用程序无需进行任何转换),但同样会增加应用程序的大小。如果图像数量很少,则可能是最简单的选择。

答案 1 :(得分:0)

只需使用filename = response.uri.replace('file:','')

最终代码:

if (Platform.OS === 'ios') {
      filename = response.uri.replace('file:', '')
} else {
      filename = response.uri
}

正在工作...