KSl*_*moe 3 winapi pipe visual-c++
我正在编写一个C++(Windows)客户端控制台应用程序,它从STDIN上的匿名管道读取.我希望能够使用我的程序如下:
echo input text here | my_app.exe
Run Code Online (Sandbox Code Playgroud)
并使用管道输入的文本在应用程序中执行某些操作
要么
my_app.exe
Run Code Online (Sandbox Code Playgroud)
然后在应用程序内部使用一些默认文本而不是管道输入.
鉴于第一种情况,我目前有代码可以在STDIN上成功读取管道:
#include <Windows.h>
#include <iostream>
#include <string>
#define BUFSIZE 4096
int main(int argc, const char *argv[]) {
char char_buffer[BUFSIZE];
DWORD bytes_read;
HANDLE stdin_handle;
BOOL continue_reading;
unsigned int required_size;
bool read_successful = true;
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
if (stdin_handle == INVALID_HANDLE_VALUE) {
std::cout << "Error: invalid handle value!\n\n";
} else {
continue_reading = true;
while (continue_reading) {
continue_reading = ReadFile(stdin_handle, char_buffer, BUFSIZE,
&bytes_read, NULL);
if (continue_reading) {
if (bytes_read != 0) {
// Output what we have read so far
for (unsigned int i = 0; i < bytes_read; i++) {
std::cout << char_buffer[i];
}
} else {
continue_reading = false;
}
}
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我知道我使用匿名管道的唯一选择是使用ReadFile进行阻塞读取.如果我理解正确,关于我如何调用它,ReadFile将继续从STDIN上的缓冲区读取,直到它检测到管道另一端的写操作结束(perhapse读取某种"写入结束")令牌?).我想知道是否有某种"开始写入"令牌将在缓冲区中,如果正在管道的东西,我可以在调用ReadFile 之前检查STDIN .如果是这种情况,我可以跳过调用ReadFile并使用一些默认文本.
如果没有办法做到这一点,我总是可以传入一个命令行参数,表示我不应该检查管道并只使用默认文本(或反过来),但我更愿意这样做我指定的方式.
看看PeekNamedPipe().尽管它的名字,它适用于命名和匿名管道.
int main(int argc, const char *argv[])
{
char char_buffer[BUFSIZE];
DWORD bytes_read;
DWORD bytes_avail;
DWORD dw;
HANDLE stdin_handle;
bool is_pipe;
stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
is_pipe = !GetConsoleMode(stdin_handle, &dw);
if (stdin_handle == INVALID_HANDLE_VALUE) {
std::cout << "Error: invalid handle value!\n\n";
} else {
while (1) {
if (is_pipe) {
if (PeekNamedPipe(stdin_handle, NULL, 0, NULL, &bytes_avail, NULL)) {
if (bytes_avail == 0) {
Sleep(100);
continue;
}
}
}
if (!ReadFile(stdin_handle, char_buffer, min(bytes_avail, BUFSIZE), &bytes_read, NULL)) {
break;
}
if (bytes_read == 0) {
break;
}
// Output what we have read so far
for (unsigned int i = 0; i < bytes_read; i++) {
std::cout << char_buffer[i];
}
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1057 次 |
| 最近记录: |