4

我希望我做错了什么,但似乎 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 可以从命名管道中读取吗?我应该放弃吗?我不认为这是一个权限问题(我尝试-m 777在我的mkfifo命令上进行设置,但这没有任何区别)。

4

4 回答 4

3

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

要实现流式传输,您可以执行以下操作:

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

然后$ cat lamb.txt > lamb.pipe

将打印

,“玛丽有只小羊羔”

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

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

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

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

在此处查看有关命名管道的更多信息。

于 2016-07-12T05:54:25.753 回答
1

失败时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)......</p>

于 2012-03-23T02:25:39.403 回答
0

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

于 2012-02-10T08:36:09.207 回答
0

从 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+ 数据库,而无需一次将数据全部保存在内存中。

于 2018-07-31T02:44:04.473 回答