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 可以从命名管道读取吗?我应该放弃吗?我不认为这是一个权限问题(我尝试在我的 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
随着版本
kdb+ v3.4 Q
支持命名管道:取决于您是要实现流算法还是仅从管道中读取,请使用.Q.fps
或read1
在 fifo 管道上:实现流式传输可以做类似的事情:
然后
$ catlambda.txt > lambda.pipe
将打印
在你的 q 会话中。通过用适当的函数替换
0N!
可以实现更有意义的算法。要将文件的上下文读入变量,请执行以下操作:
此处了解有关命名管道的更多信息。
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
orread1
on a fifo pipe:To implement streaming you can do something like:
Then
$ cat lamb.txt > lamb.pipe
will print
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:
See more about named pipes here.
当
read0
失败时,您可以经常使用system"cat ..."
来伪造它。 (我最初在尝试从 /proc 读取内容时发现了这一点,这些内容也不与read0
配合。)请注意,调用
的开销相当高(因为这些内容在 q 中) >system
——它会生成一个完整的 shell 进程来运行您的命令,您也可以直接使用 自定义 C扩展,可能直接调用
read(2)
…when
read0
fails, you can frequently fake it withsystem"cat ..."
. (i found this originally when trying to read stuff from /proc that also doesn't cooperate withread0
.)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 isyou might also be able to do it directly with a custom C extension, probably calling
read(2)
directly…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.
从 v3.4 开始支持从管道进行流式传输
详细步骤:
检查重复的管道文件
rm -f /path/dataPipeFileName
创建命名管道
mkfifo /path/dataPipeFileName
馈送数据
q).util.system[$1]; $1=获取数据的命令> /path/dataPipeFileName &
使用 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:
Check duplicated pipe file
rm -f /path/dataPipeFileName
Create named pipe
mkfifo /path/dataPipeFileName
Feed data
q).util.system[$1]; $1=command to fetch data > /path/dataPipeFileName &
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.