标准输出在流末尾暂停循环 C#

发布于 2024-11-05 17:50:02 字数 1818 浏览 0 评论 0原文

我正在读取使用 Process 启动的 java 应用程序的输出,并读取 stdError、stdOutout 并使用 stdInput 发送命令。以下是相关代码:

        int mem = Properties.Settings.Default.mem_max;
        string locale = Properties.Settings.Default.location;
        Process bukkit_jva = new Process();
        bukkit_jva.StartInfo.FileName = "java";
        //bukkit_jva.StartInfo.Arguments = "-Xmx" + mem + "M -Xms" + mem + "M -jar " + locale + "bukkit.jar";
        bukkit_jva.StartInfo.Arguments = "-Xmx512M -Xms512M -jar C:\\bukkit\\bukkit.jar";
        bukkit_jva.StartInfo.UseShellExecute = false;
        bukkit_jva.StartInfo.CreateNoWindow = true;
        bukkit_jva.StartInfo.RedirectStandardError = true;
        bukkit_jva.StartInfo.RedirectStandardOutput = true;
        bukkit_jva.StartInfo.RedirectStandardInput = true;
        bukkit_jva.Start();
        //start reading output
        SetText(bukkit_jva.StandardOutput.ReadLine());
        SetText(bukkit_jva.StandardOutput.ReadLine());
        SetText(bukkit_jva.StandardOutput.ReadLine());
        SetText(bukkit_jva.StandardOutput.ReadLine());
        StreamReader err = bukkit_jva.StandardError;
        StreamReader output = bukkit_jva.StandardOutput;
        StreamWriter writer = bukkit_jva.StandardInput;
        SetText(err.Peek().ToString());
        while (false == false)
        {
            if (vars.input != null)
            {
                writer.WriteLine(vars.input);
                vars.input = null;
            }
            SetText(output.ReadLine() + err.ReadLine());
        }
    }

SetText() 将行添加到行列表中。

我的问题是,即使没有输入,java应用程序有时也会返回一个字符串,所以我总是需要检查是否有新行。但是如果我需要发送命令,并且没有新的输出,它将不会发送。

我在 readline 上尝试了不同的 If 语句,但它只会返回前几行,然后就会停止。

基本上,如果没有新行可供读取,它似乎会暂停循环。

我怎样才能以不同的方式设置我的读/写循环或让循环取消暂停?

谢谢, 亚当

I am reading the output of a java application started using Process and reading stdError, stdOutout and using stdInput to send commands. Here is the relevant code:

        int mem = Properties.Settings.Default.mem_max;
        string locale = Properties.Settings.Default.location;
        Process bukkit_jva = new Process();
        bukkit_jva.StartInfo.FileName = "java";
        //bukkit_jva.StartInfo.Arguments = "-Xmx" + mem + "M -Xms" + mem + "M -jar " + locale + "bukkit.jar";
        bukkit_jva.StartInfo.Arguments = "-Xmx512M -Xms512M -jar C:\\bukkit\\bukkit.jar";
        bukkit_jva.StartInfo.UseShellExecute = false;
        bukkit_jva.StartInfo.CreateNoWindow = true;
        bukkit_jva.StartInfo.RedirectStandardError = true;
        bukkit_jva.StartInfo.RedirectStandardOutput = true;
        bukkit_jva.StartInfo.RedirectStandardInput = true;
        bukkit_jva.Start();
        //start reading output
        SetText(bukkit_jva.StandardOutput.ReadLine());
        SetText(bukkit_jva.StandardOutput.ReadLine());
        SetText(bukkit_jva.StandardOutput.ReadLine());
        SetText(bukkit_jva.StandardOutput.ReadLine());
        StreamReader err = bukkit_jva.StandardError;
        StreamReader output = bukkit_jva.StandardOutput;
        StreamWriter writer = bukkit_jva.StandardInput;
        SetText(err.Peek().ToString());
        while (false == false)
        {
            if (vars.input != null)
            {
                writer.WriteLine(vars.input);
                vars.input = null;
            }
            SetText(output.ReadLine() + err.ReadLine());
        }
    }

SetText() adds the line to a list of lines.

My problem is that the java app sometimes returns a string even when there is no input, so I always need to check for a new line. but If I need to send a command, and there is no new output, It will not send.

I tried different If statements on the readline, but it would only return the first few lines then it would stop.

basicly it seems to pause the loop if there is no new line for it to read.

How could I either setup my read/write loop differently or get the loop to unpause?

Thanks,
Adam

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

月光色 2024-11-12 17:50:02

试试这个:

static void Main(string[] args)
{
    ProcessStartInfo psi = new ProcessStartInfo("echoApp.exe");
    psi.RedirectStandardInput = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.UseShellExecute = false;

    Process echoApp = new Process();
    echoApp.ErrorDataReceived += new DataReceivedEventHandler(echoApp_ErrorDataReceived);
    echoApp.OutputDataReceived += new DataReceivedEventHandler(echoApp_OutputDataReceived);
    echoApp.StartInfo = psi;
    echoApp.Start();
    echoApp.BeginOutputReadLine();
    echoApp.BeginErrorReadLine();
    echoApp.StandardInput.AutoFlush = true;

    string str = "";
    while (str != "end")
    {
        str = Console.ReadLine();
        echoApp.StandardInput.WriteLine(str);
    }
    echoApp.CancelOutputRead();
    echoApp.CancelErrorRead();
    echoApp.Close();
}

static void echoApp_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine("stdout: {0}", e.Data);
}

static void echoApp_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine("stderr: {0}", e.Data);
}

还有小 echoApp...

//echoApp
static void Main(string[] args)
{
    string str="";
    while (str != "end")
    {
        str = Console.ReadLine();
        Console.WriteLine(str);
    }
}

try this:

static void Main(string[] args)
{
    ProcessStartInfo psi = new ProcessStartInfo("echoApp.exe");
    psi.RedirectStandardInput = true;
    psi.RedirectStandardOutput = true;
    psi.RedirectStandardError = true;
    psi.UseShellExecute = false;

    Process echoApp = new Process();
    echoApp.ErrorDataReceived += new DataReceivedEventHandler(echoApp_ErrorDataReceived);
    echoApp.OutputDataReceived += new DataReceivedEventHandler(echoApp_OutputDataReceived);
    echoApp.StartInfo = psi;
    echoApp.Start();
    echoApp.BeginOutputReadLine();
    echoApp.BeginErrorReadLine();
    echoApp.StandardInput.AutoFlush = true;

    string str = "";
    while (str != "end")
    {
        str = Console.ReadLine();
        echoApp.StandardInput.WriteLine(str);
    }
    echoApp.CancelOutputRead();
    echoApp.CancelErrorRead();
    echoApp.Close();
}

static void echoApp_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine("stdout: {0}", e.Data);
}

static void echoApp_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
    Console.WriteLine("stderr: {0}", e.Data);
}

and the little echoApp...

//echoApp
static void Main(string[] args)
{
    string str="";
    while (str != "end")
    {
        str = Console.ReadLine();
        Console.WriteLine(str);
    }
}
寄离 2024-11-12 17:50:02

请注意,如果您尝试在 CancelOutputRead() 和 CancelErrorRead() 之后访问输出,您可能会发现偶尔会丢失一些文本。我发现刷新仅在显式调用 Close() 后发生。处置(使用 using 语句)没有帮助。

当调用命令处理器 (CMD.EXE) 时,很可能会出现此症状,因为它不会显式刷新自身。因此,请小心不要尝试访问输出(从事件处理程序写入),除非您首先显式调用 Close()。

Please note if you try to access the output after CancelOutputRead() and CancelErrorRead() you may find that occasionally you are missing some text. I found the flush only occurs after explicitly calling Close(). Disposing (with a using statement) doesn't help.

This symptom will most likely occur when calling the command processor (CMD.EXE) because it does not explicitly flush itself. So be careful not to try and access the output (written from your event handlers) unless you explicitly call Close() first.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文