Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.02.27;
Скачать: CL | DM;

Вниз

Как читать из HANDLE построчно?   Найти похожие ветки 

 
Dmitry Koterov   (2005-01-13 18:06) [0]

Запустил я новый процесс, получил его HANDLE для stdin и stdout. Хочу теперь с ним обмениваться данными (в текстовом формате). Но найти что-то типа StringReader (который бы позволял читать/писать в HANDLE построчно) не удается. Писать же свой - можно, конечно, но, боюсь, там довольно много разных тонкостей с буферизацией.

В то же время, в идеале хотелось бы просто использовать стандартные readln/writeln. В принципе, если вызвать SetStdHandle(STD_INPUT_HANDLE, Handle), то readln начинает работать. Только проблема в том, что, если я запущу 2 процесса в параллельных потоках (как мне и нужно), будет конфликт.

В общем, ищется какой-то готовый и ОТТЕСТИРОВАННЫЙ класс, который бы "оборачивал" обычный HANDLE, позволяя работать с ним, как с текстовым файлом.


 
Dmitry Koterov   (2005-01-13 22:28) [1]

Вдруг вспомнил про такую функцию, как PeekNamedPipe. Вроде с ней все работает, сомнения только насчет определения EOF. Весь Гугл обыскал в поисках метода, как детектировать обрыв pipe или конец файла - ничего не нашел. Нет ли подводных камней в таком решении?

// Signal on EOF: ERROR_BROKEN_PIPE or ERROR_HANDLE_EOF
function EofHandle(h: THandle): boolean;
var
 buf: array[0..1] of char;
begin
 Result := not PeekNamedPipe(h, @buf, 0, nil, nil, nil);
end;

// Read one line from Win32 IO handle.
function ReadlnHandle(h: cardinal): string;
const BUF_SIZE = 256;
var
 s:      string;
 buf:    array[0..BUF_SIZE] of char;
 nRead:  DWORD;
 len, i: integer;
 foundEoln:  boolean;
begin
 s := "";
 while true do begin
   // Look ahead.
   WaitForSingleObject(h, INFINITE);
   if EofHandle(h) then begin
     Result := s;
     exit;
   end;
   PeekNamedPipe(h, @buf, BUF_SIZE, @nRead, nil, nil);
   if nRead > 0 then begin
     // Find eoln.
     len := nRead;
     foundEoln := false;
     for i := 0 to nRead-1 do begin
       if buf[i] = #10 then begin
         len := i + 1;
         foundEoln := true;
         break;
       end;
     end;
     // Read until eoln (or end of buffer).
     ReadFile(h, buf, len, nRead, nil);
     buf[nRead] := #0;
     s := s + PChar(@buf);
     if foundEoln then begin
       Result := s;
       exit;
     end
   end;
 end;
end;


 
Sumor   (2005-01-13 23:14) [2]

EOF можно определять по ReadFile - читаешь пока можно читать, как число считанных байт отличается, или ReadFile вернул FALSE, значит конец файла (или записанных данных в пайп). Можно дополнительно проверять GetLastError для  верности


 
MBo ©   (2005-01-13 23:28) [3]

>в идеале хотелось бы просто использовать стандартные readln/writeln
возможно, тебе подойдет подход, поисанный в разделе хелпа
Text-file device drivers

реализацию для TStream можно посмотреть здесь, может, будет в чем-то полезно:
http://www.mail-archive.com/fpc-pascal@lists.freepascal.org/msg02947.html



Страницы: 1 вся ветка

Текущий архив: 2005.02.27;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.031 c
3-1106671003
chistyakov
2005-01-25 19:36
2005.02.27
Альтернативный DataSource


4-1105647335
volser
2005-01-13 23:15
2005.02.27
Список процессов, которые инет юзают


14-1107344630
saNat
2005-02-02 14:43
2005.02.27
Ищу материал


1-1108368591
Koshak
2005-02-14 11:09
2005.02.27
Стрелки


14-1107335553
megabyte-ceercop
2005-02-02 12:12
2005.02.27
Может кто посмотрит первую альфу движка для игры Киркоп 3 :)