Search code examples
kdbk

Read file by its handle


q could create a file and read it content back in a nice way:

q)`:foo 0: ("bar";"baz")
`:foo
q)`:foo 0::
"bar"
"baz"

https://code.kx.com/q/ref/read0/ says than one could use read0 to get data from file or process handle. But for some reason I could not get any data from the file's handle. See no output after q)read0[h]:

q)h:hopen `:foo
q)read0[h]
q)hclose h

Moreover in .Q.fsn in each step it reads the next portion of data using 1:(s;x;n), but not by means of an open handle (like in other programming languages):

k)fsn:{[f;s;n]
 >[-7!s]
 {[f;s;x;n]
  i:(#r)^1 + last@&"\n"=r:1:(s;x;n);
  f@`\:i#r;
  x+i
 }[f;s;;n]/0}

So is it ok to use such an approach of using 1: or 0: (read0 or 0:: in q) to read data from files by their names (symbols) instead of reading them by opening the handle. And why one could not read from an open handle? But writing by file handle is ok.


Upd: Thanks, @CallumBiggs!

Great! Without handles it looks like a solid and symmetric api, for example:

gen1day:{[date;n] ([]
  sourcetime:`timestamp$date+asc 09:00:00.0 + n?08:00:00.0;
  inst:n?(1000?`4); price:n?100f; size:n?10000;
  e1:n?20; x:n?(`N`O`L`X); e2:n?10)
 }
/memory, strings
("PSFJJSJ";enlist"|") 0: "|" 0: gen1day[2020.01.01;5]
/disk, `:t0 file
("PSFJJSJ";enlist"|") 0: read0 `:t0 0: "|" 0: gen1day[2020.01.01;5]

Solution

  • Regarding your first question, read0 can read from system or process handles, not file handles. i.e., can read in from standard in.

    My point above does render your second question answered, you should read by file names, not by opening handles.

    Regarding your statement about why you can't read from open handles, but you can write from them (And why one could not read from an open handle). This is because of two factors, overloading in kdb and convention. The convention in kdb is that handles are used to send data in kdb, not to request them. I believe that under the hood kdb does open a file handle when you interact using `:path/to/file, I believe that this is hidden by operator overloading. You could check /proc/PID/fd/ to determine if a handle is opened