下载文件(使用EXPO)—为什么这么难?

Tiz*_*000 5 download react-native

我一直在尝试以多种方式将文件下载到本地存储以响应本机,但都无法正常工作。这是我在App.js中的代码,我在其中调用FileSystem.downloadAsync。

import React from 'react';
import { AppRegistry, StyleSheet, Text, View, TouchableHighlight, Image, Linking, PixelRatio, ListView } from 'react-native';
import { createStackNavigator } from 'react-navigation'
import MainScreen from './Components/MainScreen'
import FileSystem from 'react-native-filesystem';

export default class App extends React.Component {

  render() {     
    return (

      FileSystem.downloadAsync(
        'http://techslides.com/demos/sample-videos/small.mp4',
        FileSystem.documentDirectory + 'small.mp4'
      )
        .then(({ uri }) => {
          console.log('Finished downloading to ', uri);
        })
        .catch(error => {
          console.error(error);
        }),

      <AppStackNavigator />
    );
  }
}

const AppStackNavigator = createStackNavigator({
  Main:{
    screen: MainScreen
  }
})

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

AppRegistry.registerComponent('Recap', () => App);
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

在此处输入图片说明

我是本机和javascript的新手,但是为什么仅仅下载文件似乎如此困难,有帮助吗?

anr*_*nro 13

我还没有在 ios 上测试过,但它在 Android 上运行良好,将文件保存到下载目录:

import * as MediaLibrary from 'expo-media-library';
import * as FileSystem from 'expo-file-system';
import * as Permissions from 'expo-permissions';

downloadFile(){
    const uri = "http://techslides.com/demos/sample-videos/small.mp4"
    let fileUri = FileSystem.documentDirectory + "small.mp4";
    FileSystem.downloadAsync(uri, fileUri)
    .then(({ uri }) => {
        this.saveFile(uri);
      })
      .catch(error => {
        console.error(error);
      })
}

saveFile = async (fileUri: string) => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    if (status === "granted") {
        const asset = await MediaLibrary.createAssetAsync(fileUri)
        await MediaLibrary.createAlbumAsync("Download", asset, false)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的答案。但如果我下载的是音频文件或 pdf 格式怎么办?如何将它们移至我的存储空间。 (2认同)

Irf*_*mad 10

我尝试了太多的解决方案,但这对我来说非常有效。iOSAndroid 10Android 11+没有兼容性问题

进口

import * as FileSystem from 'expo-file-system';
const { StorageAccessFramework } = FileSystem;
Run Code Online (Sandbox Code Playgroud)

缩写

const [downloadProgress, setDownloadProgress] = React.useState();
const downloadPath = FileSystem.documentDirectory + (Platform.OS == 'android' ? '' : '');
Run Code Online (Sandbox Code Playgroud)

确保目录存在

const ensureDirAsync = async (dir, intermediates = true) => {
    const props = await FileSystem.getInfoAsync(dir)
    if (props.exist && props.isDirectory) {
        return props;
    }
    let _ = await FileSystem.makeDirectoryAsync(dir, { intermediates })
    return await ensureDirAsync(dir, intermediates)
}
Run Code Online (Sandbox Code Playgroud)

显示下载进度

const downloadCallback = downloadProgress => {
    const progress = downloadProgress.totalBytesWritten / downloadProgress.totalBytesExpectedToWrite;
    setDownloadProgress(progress);
};
Run Code Online (Sandbox Code Playgroud)

下载 android/ios 的 initiat

const downloadFile = async (fileUrl) => {
    if (Platform.OS == 'android') {
      const dir = ensureDirAsync(downloadPath);
    }

    let fileName = fileUrl.split('Reports/')[1];
    //alert(fileName)
    const downloadResumable = FileSystem.createDownloadResumable(
      fileUrl,
      downloadPath + fileName,
      {},
      downloadCallback
    );

    try {
      const { uri } = await downloadResumable.downloadAsync();
      if (Platform.OS == 'android')
        saveAndroidFile(uri, fileName)
      else
        saveIosFile(uri);
    } catch (e) {
      console.error('download error:', e);
    }
}
Run Code Online (Sandbox Code Playgroud)

将 android 文件保存在 public 目录中

const saveAndroidFile = async (fileUri, fileName = 'File') => {
    try {
      const fileString = await FileSystem.readAsStringAsync(fileUri, { encoding: FileSystem.EncodingType.Base64 });
      
      const permissions = await StorageAccessFramework.requestDirectoryPermissionsAsync();
      if (!permissions.granted) {
        return;
      }

      try {
        await StorageAccessFramework.createFileAsync(permissions.directoryUri, fileName, 'application/pdf')
          .then(async (uri) => {
            await FileSystem.writeAsStringAsync(uri, fileString, { encoding: FileSystem.EncodingType.Base64 });
            alert('Report Downloaded Successfully')
          })
          .catch((e) => {
          });
      } catch (e) {
        throw new Error(e);
      }

    } catch (err) {
    }
  }
Run Code Online (Sandbox Code Playgroud)

保存ios文件

  const saveIosFile = (fileUri) => {
      // your ios code
      // i use expo share module to save ios file
  }
Run Code Online (Sandbox Code Playgroud)

参考资料:https://docs.expo.dev/versions/latest/sdk/filesystem/


小智 0

替换你的

import FileSystem from 'react-native-filesystem';
Run Code Online (Sandbox Code Playgroud)

经过

import { FileSystem } from 'expo';
Run Code Online (Sandbox Code Playgroud)

  • 你是对的,但文件没有下载到设备存储...你会得到类似的信息: Finished download to file:///data/user/0/host.exp.exponent/files/ExperienceData/%2540idanlevi1%252FStartachHapRev/ hamburger.jpg 但它在设备上的哪里?无处... (7认同)
  • 我有同样的问题。下载似乎可以工作,但在设备文件系统中找不到。 (5认同)