Может ли kdb читать из именованного канала? - PullRequest
4 голосов
/ 09 февраля 2012

Я надеюсь, что я делаю что-то не так, но кажется, что 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 ]

3 голосов
/ 12 июля 2016

С выпуском kdb+ v3.4 Q есть поддержка именованных каналов: в зависимости от того, хотите ли вы реализовать алгоритм потоковой передачи или просто читать из канала, используйте .Q.fps или read1 на трубе 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"

Подробнее об именованных каналах здесь .

1 голос
/ 23 марта 2012

когда 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) - он порождает весь процесс оболочки только для запуска любой вашей команды

вы также можете сделать это напрямую с пользовательским расширением C , возможно, вызывая read(2) напрямую ...

0 голосов
/ 31 июля 2018

Потоковая передача из канала поддерживается начиная с версии 3.4

Подробности шагов:

  1. Проверить файл дублированного канала

    rm -f / path / dataPipeFileName

  2. Создание именованного канала

    mkfifo / path / dataPipeFileName

  3. Данные фида

    д) .util.system [$ 1]; $ 1 = команда для извлечения данных> / path / dataPipeFileName &

  4. Соединить трубу, используя kdb .Q.fps

    д) .Q.fps [0N!] `$ ": / Путь /", dataPipeFileName;

Ссылка: .Q.fps (алгоритм потоковой передачи) Синтаксис: .Q.fps [x; y] где x - унарная функция, а y - путь к файлу .Q.fs для труб. (Начиная с версии V3.4) Считывает из канала куски удобных размеров полных записей, разделенных "\ n", и применяет функцию к каждой записи. Это позволяет реализовать алгоритм потоковой передачи для преобразования большого CSV-файла в базу данных kdb + на диске без одновременного хранения данных в памяти.

0 голосов
/ 10 февраля 2012

Алгоритм read0 недоступен, чтобы увидеть, что он делает изнутри, но, насколько я могу судить, он ожидает конечный поток, а не непрерывный;поэтому он будет блокироваться, пока не получит сигнал EOF.

...