2016-11-22 4 views
2

Можно ли читать из именованного канала (mkfifo) с использованием C++ (stl) с использованием потока - таким образом, не определяя заранее char *buffer[MAX_SIZE] для операции чтения?Использование istream для чтения из именованной трубы

Я хочу прочитать до конца буфера и поместить результат в std::string.

(Текущий метод: bytes = read(fd, buffer, sizeof(buffer)); требует выделения какой-то буфер заранее.)

+0

фиксированное это :-) 10х – Dani

ответ

5

именованные трубы, созданные с mkfifo ведут себя как обычные файлы. Таким образом, они могут быть доступны с помощью std::ifstream и std::ofstream:

#include <fstream> 
#include <iostream> 

int main(int, char** argv) { 
    std::ifstream file{argv[1]}; 
    std::string line; 
    std::getline(file, line); 
    std::cout << line << '\n'; 
} 

Run:

mkfifo foobar 
./main foobar 

И в другом месте:

echo 'Hello world!' > foobar 

... это вызовет ./main для печати на «Привет, мир!» стандартный выход.

+1

Спасибо, я могу сделать его прочитать, пока буфер заканчивается? что происходит, если кто-то заполняет буфер, пока я читаю? – Dani

+1

@WhozCraig Uh, сбой. Починил это. –

+2

@Dani Вы читаете его как любой другой поток (см. [В другом месте] (http://stackoverflow.com/q/116038/1968)). Если ваша программа работает, пока какой-то другой процесс ее заполняет, программа будет читать до тех пор, пока другой процесс не закроет трубку. –

4

Там нет ничего магического трубопровода к вашей программе он просто превращает ваш cin чтение из потока вместо пользовательского ввода с консоли: Linux terminal pipe to my C++ program

Простой взгляд на историю изменений на этот вопрос покажет, что этот вопрос имеет очень улучшились с его оригинальной версией, благодаря Konrad Rudolph (. с другой отвечающего по этому вопросу) в ходе дальнейшей dastardliness я собираюсь скрести 2 своих решения для прихлебывая поток в string:

istreambuf_iterator method:

const string mkfifo{ istreambuf_iterator<char>(cin), istreambuf_iterator<char>() }; 

stringbuf copy method:

istringstream temp; 
temp << cin.rdbuf(); 
const auto mkfifo = temp.str(); 

Вы можете прочитать о преимуществах и недостатках каждого из них на своих постах. Чтобы использовать этот код, сказать, что ваша скомпилированная программа называется main вы бы труба к нему так:

mkfifo named_pipe 
echo "lorem ipsum" > named_pipe 
./main named_pipe 
+0

Это дает «никакой подходящей функции для вызова' getline', поскольку 'EOF' имеет неправильный тип (' int'). –

+2

Что касается вашего редактирования: что произойдет, если какой-либо другой процесс записывает 'static_cast (EOF)' в трубку, за которым следует больше содержимого (непонятный вопрос: я понятия не имею, что произойдет и будет ли поведение гарантировано, но я подозреваю, что поток будет преждевременно усечен, и я не думаю, что отлитие 'EOF' к' char' является общим решением). –

+1

@ KonradRudolph Вау, я всегда просто использовал 'EOF'. После изучения вашего комментария я явно не так умен, как я думал :( –