Домой Edit me on GitHub

2019-06-19

Каналы передачи данных | Сетевое программирование | Базы данных | Основы Веб-программирования

Передача данных через файл

Конвейер

При помощи конвейера можно передавать вывод одной команды на ввод другой. В примере показан конвейер команд: fortune, cowsay, sed, shuf.

$ fortune | cowsay -f `cowsay -l | sed '1,1d' | sed 's/ /\n/g' | shuf -n 1`
 ____________________________________
/ Лучше ничего не делать, чем делать \
| ничего.                            |
|                                    |
\ -- Л.Н.Толстой                     /
 ------------------------------------
     \         __------~~-,
      \      ,'            ,
            /               \
           /                :
          |                  '
          |                  |
          |                  |
           |   _--           |
           _| =-.     .-.   ||
           o|/o/       _.   |
           /  ~          \ |
         (____@)  ___~    |
            |_===~~~.`    |
         _______.--~     |
         \________       |
                  \      |
                __/-___-- -__
               /            _ \

Именованный канал

В программировании именованный канал или именованный конвейер (англ. named pipe) — один из методов межпроцессного взаимодействия, расширение понятия конвейера в Unix и подобных ОС.

Именованный канал позволяет различным процессам обмениваться данными, даже если программы, выполняющиеся в этих процессах, изначально не были написаны для взаимодействия с другими программами.

Пример передачи «Hello World»

../../../_images/pipe.gif

Создаем именованный канал при помощи утилиты mkfifo:

mkfifo pipe

Проверяем тип файла:

$ file pipe
pipe: fifo (named pipe)

Слушаем канал:

cat < pipe
echo "Hello World" > pipe

«Hello World» на Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# sender.py

import os

path = "/tmp/my_program.fifo"
os.mkfifo(path)

fifo = open(path, "w")
fifo.write("Hello World!\n")
fifo.close()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# receiver.py

import os
import sys

path = "/tmp/my_program.fifo"
fifo = open(path, "r")
for line in fifo:
    print("Получено: %s" % line)
fifo.close()
Полученно: Hello World!

Пример сжатия полученных данных

Можно создать канал и настроить gzip на сжатие того, что туда попадает:

mkfifo pipe
gzip -9 -c < pipe > out
cat file > pipe

В файле out запишутся переданные данные в сжатом виде.

Обычный файл как транспорт

В отличии от каналов, обычные файлы используют жесткий диск, а не ОЗУ что гораздо медленнее.

Создадим файл, через который будет происходить обмен.

$ touch pipe.txt

Будем получать данные (смотреть изменение) с помощью команды tail.

$ tail -f pipe.txt

Отправим данные обычным редактированием файла.

$ echo 'Привет' >> pipe.txt
$ echo 'файловая труба!' >> pipe.txt

Результат:

$ # Полученные данные
$ tail -f pipe.txt
Привет
файловая труба!

$ # Записанные данные в файле
$ cat pipe.txt
Привет
файловая труба!

Реализация tail -f на Python

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import time

# Open a file
file = open("pipe.txt", "r")
print("Name of the file: %s" % file.name)

while True:
    where = file.tell()
    line = file.readline()
    if not line:
        time.sleep(1)
        file.seek(where)
    else:
        print(line)  # already has newline
Previous: Межпроцессное взаимодействие Next: Сокеты