Книга: Основы программирования в Linux
Передача данных большого объема
Передача данных большого объема
Механизм, применявшийся до сих пор, просто отправляет и получает все данные в одном вызове fread
или fwrite
. Порой вам может понадобиться отправлять данные меньшими порциями или вы не будете знать размера вывода. Для того чтобы не объявлять слишком большой буфер, можно просто применить множественные вызовы fread
или fwrite
и обрабатывать данные порциями.
В упражнении 13.3 приведена программа popen3.c, читающая все данные из канала.
Упражнение 13.3. Чтение из канала данных большого объема
В этой программе вы читаете данные из вызванного процесса ps ах
. У вас нет возможности узнать заранее, какой величины будет вывод, поэтому вы должны разрешить множественные операции чтения из канала.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main() {
FILE * read_fp;
char buffer[BUFSIZ + 1];
int chars_read;
memset(buffer, '' , sizeof(buffer));
read_fp = popen("ps ax", "r");
if(read_fp != NULL) {
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
while (chars_read > 0) {
buffer[chars_read - 1] = '';
printf("Reading %d:-n %sn", BUFSIZ, buffer);
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
Вывод, отредактированный для краткости, подобен приведенному далее:
$ ./popen3
Reading 1024:-
PID TTY STAT TIME COMMAND
1 ? Ss 0:03 init [5]
2 ? SW 0:00 [kflushd]
3 ? SW 0:00 [kpiod]
4 ? SW 0:00 [kswapd]
5 ? SW< 0:00 [mdrecoveryd]
...
240 tty2 S 0:02 emacs draft1.txt
Reading 1024:-
368 tty1 S 0:00 ./popen 3
369 tty1 R 0:00 ps -ax
370 ...
Как это работает
Программа применяет функцию popen
с параметром "r"
аналогично программе popen1.c. В этот раз она продолжает чтение из файлового потока до тех пор, пока в нем есть данные. Учтите, что, хотя программе ps нужно некоторое время для выполнения, Linux так организует планирование процессов, что обе программы выполняются, когда могут. Если у читающего процесса popen3 нет входных данных, он приостанавливается до появления доступных данных. Если записывающий процесс ps формирует вывод, больший по объему, чем может вместить буфер, он приостанавливается до тех пор, пока считывающий процесс не обработает какой-то объем данных.
В этом примере строка Reading:-
может не появиться второй раз. Это означает, что BUFSIZ
больше объема вывода команды ps. В некоторых (самых современных) системах Linux установлен размер буфера BUFSIZ
, равный 8192 байт или даже больше. Для того чтобы проверить корректность работы программы при считывании нескольких порций вывода, попробуйте считывать за один раз меньше символов, чем BUFSIZ
, может быть BUFSIZ/10
.
- Резервное копирование базы данных InterBase
- Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
- Резервное копирование многофайловых баз данных
- Восстановление из резервных копий многофайловых баз данных
- Владелец базы данных
- ЧАСТЬ IV. База данных и ее объекты.
- Перевод базы данных InterBase 6.x на 3-й диалект
- Типы данных для работы с датой и временем
- Практическая работа 53. Запуск Access. Работа с объектами базы данных
- Обзор основных причин повреждения базы данных
- Ошибки проектирования базы данных
- Профилактика повреждений баз данных InterBase