kdb 可以从命名管道读取吗?

发布于 2025-01-04 05:23:13 字数 663 浏览 7 评论 0原文

我希望我做错了什么,但 kdb 似乎无法从命名管道读取数据(至少在 Solaris 上)。它会阻塞直到它们被写入,但随后不会返回任何已写入的数据。

我可以创建一个文本文件:

$ echo Mary had a little lamb > lamb.txt

并且 kdb 会很高兴地读取它:

    q) read0 `:/tmp/lamb.txt
enlist "Mary had a little lamb"

我可以创建一个命名管道:

$ mkfifo lamb.pipe

并尝试从中读取:

    q) read0 `:/tmp/lamb.pipe

将导致 kdb 阻塞。写入管道:

$ cat lamb.txt > lamb.pipe

将导致 kdb 返回空列表:

()

kdb 可以从命名管道读取吗?我应该放弃吗?我不认为这是一个权限问题(我尝试在我的 mkfifo 命令上设置 -m 777 但这没有什么区别)。

I hope I'm doing something wrong, but it seems like kdb can't read data from named pipes (at least on Solaris). It blocks until they're written to but then returns none of the data that was written.

I can create a text file:

$ echo Mary had a little lamb > lamb.txt

and kdb will happily read it:

    q) read0 `:/tmp/lamb.txt
enlist "Mary had a little lamb"

I can create a named pipe:

$ mkfifo lamb.pipe

and trying to read from it:

    q) read0 `:/tmp/lamb.pipe

will cause kdb to block. Writing to the pipe:

$ cat lamb.txt > lamb.pipe

will cause kdb to return the empty list:

()

Can kdb read from named pipes? Should I just give up? I don't think it's a permissions thing (I tried setting -m 777 on my mkfifo command but that made no difference).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

枫以 2025-01-11 05:23:13

随着版本 kdb+ v3.4 Q 支持命名管道:取决于您是要实现流算法还是仅从管道中读取,请使用 .Q.fpsread1 在 fifo 管道上:

实现流式传输可以做类似的事情:

q).Q.fps[0N!]`:lamb.pipe

然后 $ catlambda.txt > lambda.pipe

将打印

,“玛丽有一只小羊羔”

在你的 q 会话中。通过用适当的函数替换 0N! 可以实现更有意义的算法。

要将文件的上下文读入变量,请执行以下操作:

q)h:hopen`:fifo://lamb.pipe
q)myText: `char$read1(h)
q)myText

“玛丽有一只小羊羔\n”

此处了解有关命名管道的更多信息。

With release kdb+ v3.4 Q has support for named pipes: Depending on whether you want to implement a streaming algorithm or just read from the pipe use either .Q.fps or read1 on a fifo pipe:

To implement streaming you can do something like:

q).Q.fps[0N!]`:lamb.pipe

Then $ cat lamb.txt > lamb.pipe

will print

,"Mary had a little lamb"

in your q session. More meaningful algorithms can be implemented by replacing 0N! with an appropriate function.

To read the context of your file into a variable do:

q)h:hopen`:fifo://lamb.pipe
q)myText: `char$read1(h)
q)myText

"Mary had a little lamb\n"

See more about named pipes here.

与酒说心事 2025-01-11 05:23:13

read0失败时,您可以经常使用system"cat ..."来伪造它。 (我最初在尝试从 /proc 读取内容时发现了这一点,这些内容也不与 read0 配合。)

q)system"cat /tmp/lamb.pipe"
<blocks until you cat into the pipe in the other window>
"Mary had a little lamb"
q)

请注意,调用 的开销相当高(因为这些内容在 q 中) >system——它会生成一个完整的 shell 进程来运行您的命令,

您也可以直接使用 自定义 C扩展,可能直接调用read(2)

when read0 fails, you can frequently fake it with system"cat ...". (i found this originally when trying to read stuff from /proc that also doesn't cooperate with read0.)

q)system"cat /tmp/lamb.pipe"
<blocks until you cat into the pipe in the other window>
"Mary had a little lamb"
q)

just be aware there's a reasonably high overhead (as such things go in q) for invoking system—it spawns a whole shell process just to run whatever your command is

you might also be able to do it directly with a custom C extension, probably calling read(2) directly…

浮光之海 2025-01-11 05:23:13

read0 的算法无法查看它在幕后所做的事情,但据我所知,它需要一个有限的流,而不是一个连续的流;因此它将阻塞直到收到 EOF 信号。

The algorithm for read0 is not available to see what it is doing under the hood but, as far as I can tell, it expects a finite stream and not a continuous one; so it will will block until it receives an EOF signal.

酸甜透明夹心 2025-01-11 05:23:13

从 v3.4 开始支持从管道进行流式传输

详细步骤:

  1. 检查重复的管道文件

    rm -f /path/dataPipeFileName

  2. 创建命名管道

    mkfifo /path/dataPipeFileName

  3. 馈送数据

    q).util.system[$1]; $1=获取数据的命令> /path/dataPipeFileName &

  4. 使用 kdb .Q.fps 连接管道

    q).Q.fps[0N!]`$":/path/",dataPipeFileName;

参考:
.Q.fps(流媒体算法)
语法:.Q.fps[x;y] 其中 x 是一元函数,y 是文件路径
.Q.fs 用于管道。 (自 V3.4 起)从管道读取大小合适的完整“\n”分隔记录块,并将函数应用于每个记录。这使您能够实现流算法,将大型 CSV 文件转换为磁盘上的 kdb+ 数据库,而无需将数据一次性保存在内存中。

Streaming from pipe is supported from v3.4

Details steps:

  1. Check duplicated pipe file

    rm -f /path/dataPipeFileName

  2. Create named pipe

    mkfifo /path/dataPipeFileName

  3. Feed data

    q).util.system[$1]; $1=command to fetch data > /path/dataPipeFileName &

  4. Connect pipe using kdb .Q.fps

    q).Q.fps[0N!]`$":/path/",dataPipeFileName;

Reference:
.Q.fps (streaming algorithm)
Syntax: .Q.fps[x;y] Where x is a unary function and y is a filepath
.Q.fs for pipes. (Since V3.4) Reads conveniently sized lumps of complete "\n" delimited records from a pipe and applies a function to each record. This enables you to implement a streaming algorithm to convert a large CSV file into an on-disk kdb+ database without holding the data in memory all at once.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文