fs.readFileSync 总是返回空字符串

Posted

技术标签:

【中文标题】fs.readFileSync 总是返回空字符串【英文标题】:fs.readFileSync always returns empty string 【发布时间】:2016-12-16 00:33:34 【问题描述】:

我有一个脚本,可以将 API 中的数据写入某些文件。我有一个对象,其中包含每个文件的文件描述符:

var csvFds = 
    'file1' : null,
    'file2' : null,
    'file3' : null,
    'file4' : null
;

for (var file in csvFds) 

    var dirPath = __dirname + '/files/' + file;

    try 
        fs.statSync(dirPath);
    
    catch (e) 
        mkdirp.sync(dirPath, mode: 0755);
    

    csvFds[file] = fs.openSync(dirPath + '/' + moment().format("YYYY-MM-DDTHH:mm:ss[Z]") + '.csv', 'a+');

然后我有一些代码使用 fs.write 将 csv 行批量写入文件。这部分工作正常。我有格式良好的 csv 文件。现在我需要将整个文件的内容作为字符串读取。这就是我正在尝试的方式:

fs.readFileSync(csvFds['file1']).toString();

但由于某种原因,我总是得到一个空字符串。我已经确认 fs.readFileSync 实际上是通过使用 console.log 并删除 toString() 方法返回一个缓冲区。

我真的坚持这一点,所以任何帮助将不胜感激。提前致谢。以下是有关我的节点版本和操作系统的一些附加信息:

$ node -v
v6.2.3-pre

$ uname -a
Darwin i-2.local 14.5.0 Darwin Kernel Version 14.5.0: Thu Jun 16 19:58:21 PDT 2016; root:xnu-2782.50.4~1/RELEASE_X86_64 x86_64

【问题讨论】:

如果您向readFileSync 方法提供编码,您将得到一个字符串而不是Buffer 【参考方案1】:

对于有同样问题的其他人。

对我来说,获得非空字符串的唯一方法是使用 fs.readFile 而不是 fs.readFileSync。

我使用的是 Mac,我试图读取节点自己创建的文件。如果我尝试读取另一个文件,它可以工作。

fs.readFile(file, (err, data)=>
    if(err)
        console.log(err)
        throw err
    else
        let file_content = data.toString('utf8')
        // your code here
    
)

【讨论】:

即使使用异步 fs.readFile(),有时我也会遇到同样的问题。数据有时是“”,即使我可以通过在调试器中进行同步读取来验证文件是否存在并且具有非空内容。这发生在 Windows 10 上。 @Panu Logic 您正在读取被另一个流或程序使用的文件吗? 可以由我正在编辑它的编辑器使用。不确定。但我找到了解决办法。如果内容似乎是空的,我现在在我的回调函数中进行同步读取,到目前为止我似乎总是得到正确的内容 嗬,有趣。 这个解决方案适用于我,同样的情况(使用 NodeJS 12 创建的文件),但我不知道为什么会这样。有人有线索吗?【参考方案2】:

尝试像这样readFileSync(csvFds['file1'], 'utf-8') 调用readFileSync。它应该返回一个字符串。或者您可以省略参数,然后在调用 toString 方法时提供编码,例如readFileSync(csvFds['file1']).toString('utf-8')

【讨论】:

嘿迈克尔。实际上,我以前曾尝试过这两件事,然后又做了一次。但我仍然得到一个空字符串。必须有某种方法来获取有关文件描述符或缓冲区的信息以进行调试。我即将尝试切换节点版本。 您确定您的 csvFds 字典包含正确的数据吗?你能在 for 循环结束后显示 csvFds 包含的内容吗? 这是一个疯狂的猜测,但这段代码 now.getTime() 对我来说似乎有点可疑 这是 csvFds 在调用 readFileSync 之前包含的内容: file1: 13, file2: 14, file3: 15, file4: 16 我的代码版本实际上是使用 moment.js 来格式化日期不是现在.getTime()。我认为在初始循环之后文件描述符很好,因为我能够将多批数据写入这些文件而没有任何问题。 这是一个超级简单的 csv 文件,但每个文件有几千行:168722|admin 328701|developer 172090|mail 328702|team 不知道为什么换行不起作用

以上是关于fs.readFileSync 总是返回空字符串的主要内容,如果未能解决你的问题,请参考以下文章

JS:为什么fs.readFileSync()返回缓冲区,即使我之前使用toString()将其转换为字符串?

节点 fs.readFileSync 返回一个 uInt8 数组而不是原始缓冲区数组?

AJV 的验证器总是返回真值

fs.readFileSync 不是 Meteor 的函数,React

如何为 fs.readFileSync() 捕获没有文件?

Node.JS fs.readFileSync() 错误参数