写入文件时的 Kdb+ 数据格式

Kdb+ data fomat when writing to a file

我正在尝试了解当有人尝试以下一种方式写入文件时会发生什么:

q)h:hopen `:out
q)h (1 2;3)
3i
q)hclose h
q)read1 `:out
0x07000200000001000000000000000200000000000000f90300000000000000

这与二进制表示不同:

q)-8!(1 2;3)
0x010000002d00000000000200000007000200000001000000000000000200000000000000f90300000000000000

-8! returns IPC 字节表示。

磁盘上的二进制格式不同。要读取此数据,请使用 get.

要将数据流式传输到日志文件,您需要先创建空文件 https://code.kx.com/q/kb/replay-log/#replaying-log-files

q)`:out set () /This important part adds a header to the file to set the type
`:out
q)h:hopen `:out
q)h (1 2;3)
600i
q)hclose h
q)get `:out
1 2
3

请注意,如果您希望将项目作为单个元素写入列表,请使用 enlist

q)`:out set ()
`:out
q)h:hopen `:out
q)h enlist (1 2;3)
616i
q)hclose h
q)get `:out
1 2 3

二进制和文本数据也可以写入文件,这就是您正在做的。

https://code.kx.com/q/ref/hopen/#files

本意是写入具体的数据

q)h 0x2324 /Write some binary
q)h "some text\n" /Write some text

在您的代码中,原始 KX object 的二进制表示确实被写入但没有添加 header(它既不是 IPC 也不是磁盘格式)。因此,当您读回数据时,-9!get.

无法正确解释数据

使用 `:out set () 创建的有效二进制文件有一个文件 header: (可读get

q)read1 `:out
0xff0100000000000000000200000007000200000001000000000000000200000000000000f90300000000000000

带有 IPC header 的有效 IPC 二进制文件: (-9能读懂!)

q)-8!(1 2;3) 
0x010000002d00000000000200000007000200000001000000000000000200000000000000f90300000000000000

您的原始二进制 object - 没有 header 存在以启用解释

q)read1 `:out
0x07000200000001000000000000000200000000000000f90300000000000000

从技术上讲,如果您对 object 有一点先验知识,您可以阅读 object,这样您就可以编造一个 header:

q)read1`:out
0x07000200000001000000000000000200000000000000f90300000000000000
q)-9!read1`:out
'badmsg
  [0]  -9!read1`:out
         ^
q)-9!{0x01,0x000000,(reverse 0x0 vs `int$count[x]+1+3+4+1+1+4),0x00,0x00,(reverse 0x0 vs 2i),x}read1`:out
1 2
3

这里的header包括:

0x01 - little endian
0x000000 - filler
message length (count of raw `x` plus the header additions)
0x00 - type (generic list = type 0) ... you have to know this in advance
0x00 - attributes .... none here, you would have to know this
length of list .... here we knew it was a 2-item list
x  - the raw bytecode of the object without header 

正如 rianoc 所指出的,有更好的方法来编写这样的 object,这样就可以更轻松地阅读它们而无需高级知识