Форум: "WinAPI";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
ВнизКак читать из 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 вся ветка
Форум: "WinAPI";
Текущий архив: 2005.02.27;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 2.826 c