“错误:在结束后写入”与 csv-write-stream

2023-12-08

我确信这是对流工作方式的根本误解,但我正在用头撞墙。

我有一些 json 格式的传感器数据,我想使用 csv-write-stream 包将其附加到 csv 文件中。数据作为 post 请求发送到节点服务器,目的是将其附加到 csv 文件。它第一次可以很好地向 csv 文件写入一行,但如果我尝试发送另一个发布请求,则会收到“错误:结束后写入”错误。

function write_csv(obj) {
    writer.pipe(fs.createWriteStream('tides.csv', { flags: 'a' }));
    writer.write(obj);
    writer.end();
};

如果我注释掉“writer.end()”它工作正常,但这最终不会引发内存错误吗?如果是这样,附加到 csv 文件并避免此错误的正确方法是什么?

编辑:这是整个 server.js 文件

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const exphbs = require('express-handlebars');
const fs = require('fs');
const csvWriter = require('csv-write-stream');

const writer = csvWriter({ sendHeaders: false });
const app = express();

app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({ defaultLayout: 'main' }));
app.set('view engine', 'handlebars');

app.set('port', (process.env.PORT || 3000));

app.use(express.static(path.join(__dirname, 'public')));

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.get('/', function (req, res) {
    res.render('home')
})

app.post('/test', function (req, res, next) {
    // console.log("post received");
    distance = req.body.distance;
    let result = test(distance);
    let result_str = JSON.stringify(result);
    res.end(result_str)
});

function write_csv(obj) {
    writer.pipe(fs.createWriteStream('out.csv', { flags: 'a' }));
    writer.write(obj);
    writer.end();
};

function test(dist) {
    let d = new Date();
    let YYYY = d.getFullYear();
    let MM = d.getMonth();
    let DD = d.getDate();
    let HH = d.getHours();
    let mm = d.getMinutes();
    let ss = d.getSeconds();
    let date = YYYY + ':' + (MM + 1) + ':' + DD + ':' + HH + ':' + mm + ':' + ss;
    let time_distance = { 'time': date, 'distance': distance };
    console.log(time_distance);
    write_csv(time_distance);
    return time_distance;
};


app.listen(app.get('port'), function () {
    console.log('Sever started on port ' + app.get('port'));
})

如果没有看到完整的代码,我可以想象你正在调用write_csv多次,因为您试图将多个对象写入该文件。

问题是你第一次打电话时write_csv你正在结束writer,这就是为什么你第二次调用它时会得到:

Error [ERR_STREAM_WRITE_AFTER_END]: write after end

function write_csv(obj) {
    writer.pipe(fs.createWriteStream('out.csv', { flags: 'a' }))
    writer.write()
    writer.end();
}
write_csv({ hello: 'world', foo: 'bar', baz: 'taco'});
// When you call it again, writer.end(); is already closed
// The following line will trigger the error
write_csv({ hello: 'world', foo: 'bar', baz: 'taco'});

相反,您应该做的是仅在完成写入后才关闭写入器。

const writer = csvWriter(); // Create new writer
// open file
writer.pipe(fs.createWriteStream('out.csv', { flags: 'a' }));

for(const obj of objects) // Write as many times as you wish
   writer.write(obj);

writer.end(); // I'm done writing.

现在你遇到的问题是,如果你尝试执行多个.writes你将达到内存限制,因为你没有处理背压正确。

我建议阅读以下问题:

为什么尝试写入大文件会导致 js 堆内存不足

要处理这个问题,您需要等待drain要发出的事件。

这是一个包装器csvWriter这将处理背压。

const fs = require('fs');
const csvWriter = require('csv-write-stream');

class Writer {

    constructor(file) {
        this.writer = csvWriter();
        this.writer.pipe(fs.createWriteStream(file, { flags: 'a' }));
    }

    write(obj) {
        // if .write returns false we have to wait until `drain` is emitted
        if(!this.writer.write(obj))
            return new Promise(resolve => this.writer.once('drain', resolve))

        return true;
    }

    end() {
        // Wrap it in a promise if you wish to wait for the callback.
        this.writer.end(); 
    }

}

(async() => {
    const writer = new Writer('out.csv');

    for(let i = 0; i < 1e8; i++) {
        const res = writer.write({ hello: 'world', foo: 'bar', baz: 'taco' });
        if(res instanceof Promise) {
            // You can remove this if, and leave just: await writer.write...
            // but the code will be slower
            await res; // This will wait for the stream to emit the drain event
        }
    }

    writer.end();

})();

Update:现在有了实际的代码,上面的答案仍然有效,但是因为您在收到请求时正在写入文件。您可以选择是否打开文件一次,并在每个请求上写入,在服务器关闭时(或您选择时)关闭它。或者只是打开文件,写入文件,然后根据每个请求关闭它,

对于前者,您应该使用上面的答案,对于后者,您需要做的就是每次调用时创建一个新的 writerwrite_csv而不是只有一位全球作家。

function write_csv(obj) {
    // Create a new writer every time
    const writer = csvWriter({ sendHeaders: false }); 
    writer.pipe(fs.createWriteStream('out.csv', { flags: 'a' }));
    writer.write(obj);
    writer.end();
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“错误:在结束后写入”与 csv-write-stream 的相关文章

  • 将实时流音频从 NodeJS 服务器获取到客户端

    我需要从 1 个客户端到服务器到多个侦听器客户端的实时实时音频流 目前 我正在从客户端进行录音 并通过 socket io 将音频流式传输到服务器 服务器接收此数据 并且必须将音频流式传输 也通过 socket io 到想要收听此流的客户端
  • 如何动态删除嵌套的json键?

    这是示例 json search facets author language value nep count 3 value urd count 1 source value West Bengal State Council of Vo
  • 网络上的等角柱状图

    我计划为游戏的标记 图钉 构建在线地图 但我无法设置标记的正确纬度 原始地图是一个2048 2048px 的正方形 然后我得到了标记 数千个 地图坐标使用 0 到 100 之间的 x y 表示法设置 0 0 是top left角和100 1
  • ASP.NET 验证控件和 Javascript 确认框

    我有一个使用 NET 服务器端输入验证控件的页面 此页面还有一个 javascript 确认框 在提交表单时会触发该确认框 当前 当选择 提交 按钮时 会出现 javascript 确认框 一旦确认 就会触发 ASP NET 服务器端验证控
  • 在动态创建的元素的onclick函数的属性中传递一个字符串

    我试图在动态创建的锚元素的 onClick 事件处理函数的参数中传递一个字符串 请参阅小提琴http jsfiddle net shmdhussain bXYe4 http jsfiddle net shmdhussain bXYe4 我无
  • 为什么我可以使用 Date 对象进行数学运算? [复制]

    这个问题在这里已经有答案了 当我像这样减去两个日期对象时 const startTime new Date await someAsyncStuff const endTime new Date const elapsedTime endT
  • 早于 0.4.12 的 Node.js 无法在 AWS EC2 上正常工作。为什么?

    我无法在 AWS EC2 Ubuntu 或 CentOs 没关系 上安装 node js v0 6 1 安装后我输入node 处理器负载达到100 但 v0 4 12 工作正常 可能只有我有这个问题 那不好意思了 请告诉我我做错了什么 提前
  • 无需重定向的 HTML 页面提交

    有没有什么方法可以在不使用ajax的情况下提交html表单而无需从当前页面重定向 你可以设置一个target 为您form 这样您就可以将表单提交到新选项卡 target blank 或一个小的 隐藏的iframe target nameo
  • 仅从功能区打开一个对话框

    我有一个带有登录按钮的功能区 可打开登录对话框 我想将对话框的数量限制为一个 我正在使用函数 displayDialogAsync startAddress options callback https learn microsoft co
  • 为什么Promise中的代码会同步执行? [复制]

    这个问题在这里已经有答案了 在我的项目中 我有一个很长时间运行的操作 所以我决定将其放入Promise因为我认为这样我就可以在里面的代码继续执行其他操作Promise正在跑步 调试的时候发现外面的代码Promise仅当里面的代码执行Prom
  • NodeJS - 将相对路径转换为绝对路径

    In my 文件系统我的工作目录在这里 C temp a b c d 在 b bb 下有文件 tmp txt C temp a b bb tmp txt 如果我想从工作目录转到该文件 我将使用以下路径 bb tmp txt 如果该文件不存在
  • 如何在数据表角度中基于 JSON 动态填充表值?

    我在用着Angular 数据表 https l lin github io angular datatables 我需要能够根据返回的数据动态创建表 换句话说 我不想指定列标题 Example json数据 id 2 city Baltim
  • JS:修改 JS 对象中的值/对

    我正在尝试找出修改对象的最佳方法 而无需三次写出类似的对象 所以我有这三个对象 var object1 start start end end type 1 var object2 start start end end type 2 va
  • 为什么 console.log() polyfill 不使用 Function.apply()?

    我一直在看一些流行的console log 包装 填充 保罗 爱尔兰的 http paulirish com 2009 log a lightweight wrapper for consolelog 本阿尔曼的 http benalman
  • 从浏览器访问本地文件?

    您好 我想从浏览器访问系统的本地文件 由于涉及大量安全检查 是否可以通过某种方式实现这一目标 或使用 ActiveX 或 Java Applet 的任何其他工作环境 请帮帮我 要通过浏览器访问本地文件 您可以使用签名的 Java Apple
  • 如何让php页面从html页面接收ajax post

    我有一个非常简单的表单 其中有一个名字输入字段 我捕获了表单数据 并使用标准 jQuery 发布方法通过 ajax 将其传输到 PHP 页面 但是 我根本无法从 PHP 页面获得任何在服务器端捕获数据的响应 我不确定我做错了什么或缺少什么
  • chrome 选项卡/窗口中的 window.open 行为

    我有一小段 javascript 旨在打开两个或更多选项卡 这在 FF 和 IE 中工作正常 但 chrome 会在新窗口而不是选项卡中打开第二个窗口 它不依赖于 url 因为我已经尝试过使用两个相同的 url 第一个在选项卡中打开 第二个
  • WebpackError:ReferenceError:Gatsby 上未定义窗口

    我已经在互联网上进行了大量搜索 但无法解决这个问题 我正在使用 Gasby 开发静态页面 但遇到此错误 WebpackError ReferenceError window is not defined 我的线索是 这与我正在使用的引导 模
  • eventSources 到事件 Json,完整日历

    我正在尝试从 eventSources 获取 json 调用到我的事件 我在 eventSources 中返回的 json 是 title Title Test start 1305841052 当我将此字符串传递到事件中时 它会正确显示日
  • 在引导程序中以编程方式更改选项卡窗格选项卡

    我使用的选项卡窗格定义为 ul class nav nav tabs li a href personal Personal Information a li li class active a href contact Contact a

随机推荐

  • Sequential Guid 主键列应该是聚集索引吗?

    使用顺序 guid 的目标是 您可以使用聚集索引 而不会产生高级别碎片 如果它是常规 guid 那么聚集索引中通常会存在这种情况 对吗 首先澄清一下 主键和聚集索引是两个独立且不同的东西 即一个不与另一个耦合 PK 可以是非聚集的 聚集索引
  • 在g++编译器中使用strlen获取数组的长度

    有人可以解释为什么当我使用以下 g 编译器编译源代码时出现此错误 include
  • 降低 OpenCV 中的图像分辨率

    我正在使用 OpenCV 从 A4Tech 相机捕获图像 当我尝试降低图像分辨率时 图像断言失败 CvCapture camera cvCreateCameraCapture 1 0 is index of Laptop integrate
  • PHP:格式化时间 Stackoverflow 或 Apple Mail 风格

    有这个php net 文档中的非常好的功能使您能够以 Facebook 风格的方式格式化时间 例如 2 minutes ago 4 weeks ago or 3 years ago 不过 我更喜欢 Stackoverflow 和 Apple
  • Python 深度压缩

    我正在尝试编写一个像 zip 这样的函数 我不擅长解释我的意思 所以我只会显示我正在尝试做的事情的 代码 a 1 2 3 4 5 b a zip a b 1 1 2 2 3 3 4 5 4 5 myzip a b 1 1 2 2 3 3 4
  • Django 使用 postgres 进行测试 - 重置序列

    到目前为止 开发和测试已经在 SQLite 上完成 而生产则在 Postgres 上完成 现在一切都需要在 Postgres 上运行 并且大量测试失败了 原因是 每个测试的 ID 不是以 1 开头 而是在测试之间继续 解决此问题的一种方法是
  • Powershell:根据创建日期将文件移动到文件夹

    我不是编码员 但我仍然尝试调整此处找到的 PS 脚本 但仍然无法获得我想要的行为 对我来说最困难的部分是 2 位数的日要求 dd 经过几次菜鸟尝试后 我需要一些帮助 我有一个包含数百张 JPG 的文件夹 我根据拍摄日期手动将这些 JPG 分
  • 获取 jQuery 和/或 DOM 对象的 HTML 字符串

    我想我已经读完了全文jQuery API 文档并在调试器中查看 jQuery 对象和简单的 DOM 元素 以检查它们在运行时实际拥有的方法 但对于我来说 我找不到一种方法来获取表示 jQuery 对象内容的 html 字符串或一个 DOM
  • Java - 滚动到 JTextArea 内的特定文本

    我正在尝试在我正在编写的当前程序中实现一个功能 并且我想学习如何向下滚动到 JTextArea 中的特定文本 例如 假设我有以下内容 JTextArea area new JTextArea someReallyLongString som
  • 如何按升序打印奇数? [复制]

    这个问题在这里已经有答案了 我需要按升序打印一系列奇数 我只能按降序解决它 num int input print Type any integer count 1 while count lt num num 1 if num 2 0 p
  • 通过异步 JavaScript (Mocha) 进行循环测试

    我正在尝试使用 Mocha 测试异步 JavaScript 但在循环异步填充数组时遇到一些问题 我的目标是创建 N arr length 测试 数组的每个元素一个 可能我缺少一些关于摩卡语义的东西 到目前为止 这是我的 非工作的 简化代码
  • 如何从 wxPython 中的 wx.TextCtrl 控件获取滚动位置/范围

    我有一个小型日志记录应用程序 用 wxPython 编写 它从我们正在开发的一些套件接收数据 并且我想在滚动窗口中显示文本 就目前情况而言 我使用 wx TextCtrl 进行文本显示 但滚动行为存在一些问题 基本上 我希望如果滚动条位于窗
  • BinaryReader ReadString指定长度?

    我正在开发一个解析器来接收 UDP 信息 解析它并存储它 为此 我正在使用BinaryReader因为它主要是二进制信息 但其中一些将是字符串 MSDN 说为了ReadString 功能 从当前流中读取字符串 该字符串的前缀为 长度 一次编
  • Android:从java脚本到java的回调函数

    我创建了一个应用程序 在其中使用 webview 并加载一个简单的静态 html 页面 我正在从活动调用 java 脚本函数 但无法从 java 脚本调用函数 我尝试了一些链接 但没有成功 Javascript回调函数传递给Android
  • 在 Quartz.Net 中为 BiWeekly 作业配置 CronString

    如何为以下作业配置 Quartz Net 作业调度程序的 CronString 作业应在周一中午 12 00 在 BiWeekly 上运行 即它应该在每个星期一运行 但中间会跳过一周 例子 1st Run gt 19 Nov 2012 Mo
  • 执行 JSF 导航时,不会调用映射到转发调度程序的过滤器

    我正在尝试使用 Tomcat 7 编写一个带有登录系统的简单 JSF Web 应用程序 我有两个页面 index xhtml 和 restricted welcome xhtml restricted 下面的页面只能由登录的用户访问 直接浏
  • JAVA:是否可以在循环外使用已在循环内初始化的变量?

    我是一名新程序员 试图通过制作游戏来练习 我希望玩家能够设置自己的名字 并回答 是 或 否 这个名字是否正确 我通过使用 while 循环来做到这一点 但是 由于该名称是在循环内部初始化的 因此我无法在外部使用它 我想知道是否有办法这样做
  • 如何针对不连续的元素中断 XSLT for-each 循环?

    我有一个具有以下结构的结构化 XML
  • HTML Canvas 剪辑和 putImageData

    我有一个画布 背景中有一个大图像 前面有一个较小的圆形图像 我通过像这样使用剪辑实现了这种圆形图像效果 ctx save ctx beginPath ctx arc x y r 0 Math PI 2 true ctx closePath
  • “错误:在结束后写入”与 csv-write-stream

    我确信这是对流工作方式的根本误解 但我正在用头撞墙 我有一些 json 格式的传感器数据 我想使用 csv write stream 包将其附加到 csv 文件中 数据作为 post 请求发送到节点服务器 目的是将其附加到 csv 文件 它