我试图读取文件,但我总是收到错误Error: ENOENT: no such file or directory, open \'SB01028A.RET\'
。文件名是正确的,并且存在,因为我将文件放在我的Home / sentbox目录中。
我在这里做错了什么?
代码:
function downloadFile () {
return new Promise((resolve, reject) => {
try {
const testFolder = `${require('os').homedir()}/sentbox`
fs.readdir(testFolder, (err, files) => {
if (err) {
return reject(err)
}
files.forEach(fileRetorno => {
const retorno = fs.readFileSync(fileRetorno, 'UTF8')
return resolve(retorno)
})
})
} catch (err) {
return reject(err)
}
})
}
答案 0 :(得分:0)
您的代码中存在许多错误,例如
try/catch
,而不将其包含在async/await
函数fs.readdir()
的结果。 require()
fs.readdir()
将返回该目录中的所有条目名称,包括文件和目录,作为数组。在调用fs.readFile()
之前,您需要检查条目是文件还是目录,在这种情况下,您需要join()
使用readdir()
读取目录的路径, testFolder
,条目名称。
使用Promises返回时(async/await
包装承诺但仍然使用它们),您只能解决一次承诺。因此,多次解析相同的承诺以返回不同的值不起作用,拒绝多次也是如此。相反,您需要在Array或Object中返回值。对于上面代码中的场景,使用Object会更理想,因为您可以将文件内容关联到一个键以供参考,以便以后更好地访问。
我已经使用async/await
来清理这段代码,这将为您提供同步开发方法,同时获得promises的功能。您可以在MDN上详细了解async/await
。我还使用util.promisify()
fs
函数的异步版本
以下代码
testFolder
stat()
并检查它是否是文件,将条目数组过滤为仅包含文件。
stat()
将返回fs.Stat
对象,该对象可以通过stat.isFile()
告诉我们该条目是否为文件。由于Array#filter()
只期望对每个条目进行一次布尔结果,因此stat.isFile()
的结果可以直接返回files
对Array#reduce()
数组进行迭代,并为每个文件调用readFile()
,并在对象上返回内容,并将每个文件名作为内容的关键const fs = require('fs')
const {promisify} = require('util')
const os = require('os')
const path = require('path')
const readdir = promisify(fs.readdir)
const readFile = promisify(fs.readFile)
const stat = promisify(fs.stat)
const downloadFile = async () => {
const testFolder = `${os.homedir()}/sentbox`
// Get all the entries in the directory async
const entries = await readdir(testFile)
// We only want the file entries returned
const files = entries.filter(async entry => {
let stat = await stat(path.join(testFolder, entry))
return stat.isFile()
})
return Promise.all(files.reduce(async (filesContents, file) => {
let filepath = path.join(testFolder, file)
fileContents[file] = await readFile(filepath, 'utf8')
return fileContents
}, {}))
}