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

时间:2012-02-09 15:44:04

标签: solaris named-pipes kdb

我希望我做错了,但似乎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 个答案:

答案 0 :(得分:3)

发布kdb+ v3.4 Q支持命名管道:根据您是要实现流式算法还是只读取管道,请使用fifo管道上的.Q.fpsread1

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

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

然后$ cat lamb.txt > lamb.pipe

将打印

  

,"玛丽有一只小羊羔"

在你的q会话中

。通过用适当的函数替换0N!,可以实现更有意义的算法。

要将文件的上下文读入变量do:

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

"玛丽有一只小羊羔\ n"

详细了解命名管道here

答案 1 :(得分: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)

请注意,调用system会有相当高的开销(因为这样的事情会进入q) - 它会生成一个完整的shell进程,只是为了运行你的命令

您也可以直接使用custom C extension进行操作,可能直接调用read(2) ...

答案 2 :(得分:0)

read0的算法无法看到它在幕后做了什么,但据我所知,它预计有限流而不是连续流;所以它会阻止,直到它收到一个EOF信号。

答案 3 :(得分:0)

从v3.4开始支持管道流

详细步骤:

  1. 检查重复的管道文件

    rm -f / path / dataPipeFileName

  2. 创建命名管道

    mkfifo / path / dataPipeFileName

  3. Feed数据

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