如何修复JavaScript中的“错误:生成ENAMETOOLONG”(可能是jq引起的)?

bos*_*972 5 javascript node.js jq

我在Windows 10上,并且使用node.js,并且使用node-jq@1.10.0(目前是最新版本)

我想使用jq从JSON检索一些信息。所以我使用带有'json'作为选项参数的jq.run函数。但这给我带来了一个错误,我知道我的查询很好,并且我的所有代码都可以运行,而无需以“ let AllKOMoves = ... ” 开头的行。

我的JSON格式正确,我在JMES Path中尝试了该程序,并且运行良好,因此JSON没有问题。我做了一些研究,有人说我的操作系统不能支持太长的请求。我想精确指出JSON上的权重为6Mo。

我在互联网上做过一些研究,其中一些谈论在此网站上的“ 未指定.catch(…) ”:这里和这个谈论过长的查询这里

这是我const jq = require('node-jq');退出异步功能的代码。

(async ()=>{
    let name = "abomasnow"; 
    const fileContent = fs.readFileSync(`./Pokemon with move CSV/Queries/nonStatusMove/${name}nonStatusMove.csv`);
    let pokemonSubject = JSON.parse(await jq.run(`. | map(select(.name == "${name}"))[0]`, './nameBSTypeAbilityWeight.json'));
    var allMoves = moveToJSON(fileContent);
    let AllKOMoves = await jq.run(`. | map(select(.Moves | map(select(.Max == 100)) | length > 1)) | map({Nature: .Nature, EV: .EV, Moves: [.Moves | map(select(.Max == 100))[] | .Move], MovesCount: .Moves | length})`,getAllInflictedDamage(pokemonSubject, allMoves, pokemonJSON[0]),{ input: 'json' })
    console.log(AllKOMoves);
    })();
Run Code Online (Sandbox Code Playgroud)

这是这部分代码生成的JSON示例getAllInflictedDamage(pokemonSubject, allMoves, pokemonJSON[0])

[  
   {  
      "Opponent":"abomasnow",
      "Move":"wood-hammer",
      "Min":16.15,
      "Max":19.25,
      "Crit":28.88
   },
   {  
      "Opponent":"abomasnow",
      "Move":"round",
      "Min":15.84,
      "Max":18.94,
      "Crit":28.26
   }
]
Run Code Online (Sandbox Code Playgroud)

这是变量中包含的JSON的示例allMoves

[  
   {  
      "name":"bulldoze",
      "accuracy":"100",
      "category":"physical",
      "power":"60",
      "priority":"0",
      "target":"all-other-pokemon",
      "type":"ground"
   },
   {  
      "name":"frost-breath",
      "accuracy":"90",
      "category":"special",
      "power":"60",
      "priority":"0",
      "target":"selected-pokemon",
      "type":"ice"
   }
]
Run Code Online (Sandbox Code Playgroud)

我期望JSON的内容,但是会引发以下错误消息:

(node:21792) UnhandledPromiseRejectionWarning: Error: spawn ENAMETOOLONG
    at ChildProcess.spawn (internal/child_process.js:366:11)
    at Object.spawn (child_process.js:538:9)
    at C:\Users\adela\node_modules\node-jq\lib\exec.js:24:43
    at new Promise (<anonymous>)
    at exec (C:\Users\adela\node_modules\node-jq\lib\exec.js:20:10)
    at C:\Users\adela\node_modules\node-jq\lib\jq.js:24:24
    at new Promise (<anonymous>)
    at Object.run (C:\Users\adela\node_modules\node-jq\lib\jq.js:19:10)
    at C:\Users\adela\node_code\calcDamage1forAll.js:757:28
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:21792) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:21792) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Run Code Online (Sandbox Code Playgroud)

通常,我的代码应检索如下信息:

[  
   {  
      "Nature":"brave",
      "EV":[  
         4,
         0,
         0,
         0,
         252,
         252
      ],
      "Moves":[  
         "focus-punch",
         "natural-gift-fire90",
         "natural-gift-fire100",
         "natural-gift-fire80"
      ],
      "MovesCount":4
   },
   {  
      "Nature":"brave",
      "EV":[  
         0,
         252,
         252,
         4,
         0,
         0
      ],
      "Moves":[  
         "natural-gift-fire90",
         "natural-gift-fire100",
         "natural-gift-fire80"
      ],
      "MovesCount":3
   }
]
Run Code Online (Sandbox Code Playgroud)

编辑:如果我只这样做:

(async ()=>{
    let name = "abomasnow"; 
    const fileContent = fs.readFileSync(`./Pokemon with move CSV/Queries/nonStatusMove/${name}nonStatusMove.csv`);
    let pokemonSubject = JSON.parse(await jq.run(`. | map(select(.name == "${name}"))[0]`, './nameBSTypeAbilityWeight.json'));
    var allMoves = moveToJSON(fileContent);
    let AllKOMoves = await jq.run(`. | map(select(.Moves | map(select(.Max == 100)) | length > 1)) | map({Nature: .Nature, EV: .EV, Moves: [.Moves | map(select(.Max == 100))[] | .Move], MovesCount: .Moves | length})`,getAllInflictedDamage(pokemonSubject, allMoves, pokemonJSON[0]),{ input: 'json' })
    console.log(AllKOMoves);
    })();
Run Code Online (Sandbox Code Playgroud)

它也给我同样的错误!

EDIT2:如果我这样做:

[  
   {  
      "Opponent":"abomasnow",
      "Move":"wood-hammer",
      "Min":16.15,
      "Max":19.25,
      "Crit":28.88
   },
   {  
      "Opponent":"abomasnow",
      "Move":"round",
      "Min":15.84,
      "Max":18.94,
      "Crit":28.26
   }
]
Run Code Online (Sandbox Code Playgroud)

它完美地工作!通过一些研究,我认为它的大小与json差不多,因为我的json大小为〜12Mo,我尝试使用300 Ko的json也不起作用,所以我认为只是json太大。

我的问题现在是要知道是否存在其他创建像第一个答案中所建议的那样的临时文件的解决方案...

los*_*der 4

编辑:

由于这个问题,现在已经在node-jq 1.10.0 ( pull #191 )中重新检查并解决了这个问题,因此确保项目依赖项中的 node-jq 版本是最新的应该可以防止出现此错误。

node-jq 1.10.0 之前的背景(或研究 ENAMETOOLARGE 问题的人)

除了“文件”之外的问题input:在于,它会被 1.10.0 之前的 node-jq 版本翻译成命令行,jq --null-input '[json] | [filter]'因此您的 JSON 和过滤器组合必须小于操作系统最大可接受的单个参数和/或总参数限制,在 Windows 上,这可能小至 8192 字节。(对于 128-256k 左右的参数,大多数 UNIX 克隆应该会失败并出现E2BIG 错误。)

要通过早期版本的 node-jq 将大量数据传递给 jq,而不直接通过命令行参数,您需要写入名称以 .json 结尾的临时文件,以便在 JSON 大小足够大时使用它来传递{input:file}JSON 。

理论上,您可以提供一个[]for 文件数组,使 jq 通过 stdin 等待数据,node-jq包装子进程,因此获取其 stdin 的句柄将是丑陋的。随后,它需要被修复,或者需要编写一个替代包装器来通过 stdin 将数据传递给 jq,例如:

child_process.spawn... 
process.stdin.write('myJsonAsAstring')
process.stdin.end()
Run Code Online (Sandbox Code Playgroud)

进一步的讨论可以在原始的node-jq问题中找到。