【问题标题】:How to read JSON file with React-Native-fs如何使用 React-Native-fs 读取 JSON 文件
【发布时间】:2019-11-25 09:30:53
【问题描述】:

我有一个包含内容的 assets.json 文件,需要在 react-native 应用程序中读取它。 我已经认为它必须手动复制到本机实现,并且我可以验证文件是否存在(并且可读:-rw-r--r--)。 既然它在那里并且我正在使用承诺来获取它,请告诉我输出仍然是什么:

{"_40":0,"_65":0,"_55":null,"_72":null}

而不是文件的内容。

const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  const asset_content = await RNFS.readFile(path);
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

输出是:

[10:03:55] I | ReactNativeJS ▶︎ BLAH EXISTS

[10:03:55] I | ReactNativeJS ▶︎ 'local asset_content:', '{"_40":0,"_65":0,"_55":null,"_72":null}'

[10:03:55] I | ReactNativeJS ▶︎ 'local assets:', { _40: 0, _65: 0, _55: null, _72: null }

另一方面,如果我出于某种原因使用promisify,正如某些帖子中所建议的那样,应用程序会冻结对已读取文件的调用。 这里是应用更改的代码:

 const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  const readFileAsync = promisify(RNFS.readFile);
  const asset_content = await readFileAsync(path);
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

及其输出:

[10:24:16] I | ReactNativeJS ▶︎ BLAH EXISTS

文件不大,只有 81 行有效的 JSON。 现在,如果我使用 Promise 来检查任何这样的异常:

  const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  const readFileAsync = promisify(RNFS.readFile);
  let asset_content = null;
  readFileAsync(path, 'utf8')
    .then((str) => {
      console.log("got result: ", str);
      asset_content = str;
    })
    .catch((e) => {
      console.log("got error:", e);
    });
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

我还是没有异常,结果为null:

[10:45:00] I | ReactNativeJS ▶︎ BLAH EXISTS

[10:45:00] I | ReactNativeJS ▶︎ 'local asset_content:', null

[10:45:00] I | ReactNativeJS ▶︎ 'local assets:', null

当我摆脱 Promisify 并离开 Promise 处理时,我又回到了我开始的地方:

  const path = RNFetchBlob.fs.dirs.DocumentDir + '/' + ASSET_FILENAME;
  if (await RNFS.exists(path)){
    console.log("BLAH EXISTS");
  } else {
    console.log("BLAH DOES NOT EXIST");
  }
  let asset_content = null;
  RNFS.readFile(path, 'utf8')
    .then((str) => {
      console.log("got result: ", str);
      asset_content = str;
    })
    .catch((e) => {
      console.log("got error:", e);
    });
  console.log("local asset_content:", asset_content);
  const assets = JSON.parse(asset_content);
  console.log("local assets:", assets);

输出:

[10:49:45] I | ReactNativeJS ▶︎ BLAH EXISTS

[10:49:45] I | ReactNativeJS ▶︎ 'local asset_content:', null

[10:49:45] I | ReactNativeJS ▶︎ 'local assets:', null

[10:49:45] I | ReactNativeJS ▶︎ 'got result: ', '{"_40":0,"_65":0,"_55":null,"_72":null}'

请帮忙。文件处理对我们的应用程序至关重要。

更新: 下面是使用 ASSET_FILE 引用的文件asset.json 的内容:

{
  "protobuf": [
    {
      "name": "tiny-fovapp-4c",
      "lite": false,
      "compressed": false,
      "selected": false
    },
    {
      "name": "tiny-yolo-4c-quantized",
      "lite": true,
      "compressed": true,
      "selected": false
    },
    {
      "name": "tiny-yolo-4c",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilePath": "ai/protobuf/tiny-yolo-4c.pb",
      "labelsFilePath": "ai/protobuf/tiny-yolo-4c-labels.txt",
      "lite": false,
      "compressed": false,
      "selected": true
    },
    {
      "name": "tiny-yolo-4c",
      "lite": true,
      "compressed": false,
      "selected": false
    }
  ],
  "testImages": [
    {
      "name": "IMG_6924.jpg",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/IMG_6924.jpg"
    },
    {
      "name": "IMG_6924.png",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/IMG_6924.png"
    },
    {
      "name": "IMG_6929.jpg",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/IMG_6929.jpg"
    },
    {
      "name": "Part1.png",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/Part1.png"
    },
    {
      "name": "Part1_10.png",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "filePath": "ai/testimgs/Part1_10.png"
    }
  ],
  "parts": [
    {
      "name": "Part1",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilename": "ai/models/Part1.png",
      "drawingFilename": "ai/drawings/Part1.png",
      "annotationFilename": "ai/annotations/Part1.xml"
    },
    {
      "name": "Part2",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilename": "ai/models/Part2.png",
      "drawingFilename": "ai/drawings/Part2.png",
      "annotationFilename": "ai/annotations/Part2.xml"
    },
    {
      "name": "Part3",
      "parentFolder": "/data/user/0/com.foviar/files/",
      "modelFilename": "ai/models/Part3.png",
      "drawingFilename": "ai/drawings/Part3.png",
      "annotationFilename": "ai/annotations/Part3.xml"
    }
  ]
}

【问题讨论】:

  • 这不是你的答案,但我更喜欢使用npmjs.com/package/react-native-file-picker 而不是直接 fetch-blob,因为不同手机的手机和平台和操作系统版本相互不兼容。并且需要花费太多时间。
  • 您是否在为在 react native 应用程序中读取 json 文件而苦恼?
  • 是的,非常。我可以读取从服务器下载的文件,但不能读取与应用程序捆绑在一起并保存在 android/app/src/main/assets 中的文件
  • 你为什么不试试 readFileAssets() :github.com/itinance/…
  • @Macilias 如果可行,则意味着很可能是库问题。有一个库仅用于从 Android 和 iOS 中的资产中读取文件。可能值得一试:github.com/IgorBelyayev/React-Native-Local-Resource

标签: reactjs react-native react-native-fs rn-fetch-blob


【解决方案1】:

在 react-native 应用程序中读取 json 文件的步骤:-

1.将其导入您的组件中

import ASSET_FILE from '../assets/files/asset.json';

// import filename from '你的资产文件的路径';

2。现在在一个函数中

jsonParser(){
    var data = JSON.parse(JSON.stringify(ASSET_FILE));
    var tempProtobuf = []
    var temptestImages= []
    var tempparts= []
    tempProtobuf = data.Protobuf
    temptestImages = data.testImages
    tempparts = data.parts
}

// Now three of your objects are there in tempProtobuf, temptestImages, tempparts array respectively.

如果您想在应用程序中显示,请迭代或保存状态..

希望这会有所帮助...谢谢:)

【讨论】:

  • 我想使用静态和动态资源。 Import/Require 方法仅适用于静态资源,并且关于另一个区别 - 在应用 JSON.parse() 之前添加 JSON.stringify(),这不会改变任何事情。两者都应用后,assets还是'{"_40":0,"_65":0,"_55":null,"_72":null}'除此之外,如果这样使用静态资源,有没有办法把文件保存回来?
  • 是的,@Macilias 是动态的,您可以在处理动态数据时将变量名称从 ASSET_FILE 更改为响应数据变量名称
  • 您不能将变量用于导入/要求。这就是为什么这种方法如此 *#&D=
  • getting '{"_40":0,"_65":0,"_55":null,"_72":null}' 这意味着你在你的承诺中做错了什么,任何语法错误等等......这就是你得到这个的原因。
  • 嘿@Macilias 它在我的最后工作,我还阅读了大量的 json 文件 static/dynamic 。这就是为什么我已经回答了同样的问题。请看一下,它可以工作...如果您还有一些问题,请随时询问..谢谢:)
【解决方案2】:

我最终设法将静态文件的内容复制到应用程序文档目录中,并通过使用带有提供的编码参数的 NRFechtBlob.fs 实现来读取和维护它,如下所示:

let asset_content = null;
try {
    await RNFetchBlob.fs.readFile(assetFile_path, 'utf8')
      .then((data) => {
        asset_content = data;
        console.log("got data: ", data);
      })
      .catch((e) => {
        console.error("got error: ", e);
      })
  } catch (err) {
    console.log('ERROR:', err);
}
const assets = JSON.parse(asset_content);

呸。没想到文件处理在 2019 年会这么痛苦。

【讨论】:

    猜你喜欢
    • 2018-05-29
    • 2020-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    • 2016-11-27
    • 1970-01-01
    相关资源
    最近更新 更多