【问题标题】:Java - passing input into external C/C++ applicationJava - 将输入传递到外部 C/C++ 应用程序
【发布时间】:2009-09-14 12:32:35
【问题描述】:

我正在尝试使用 Java 在外部应用程序中输入一些值。

Java 应用程序如下所示:

Runtime runtime = Runtime.getRuntime();
// ... str build ...
proc = runtime.exec(str);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(proc.getOutputStream()));
bw.write(value);
bw.flush();
bw.close();
if (proc.waitFor() != 0) 
    // error msg
// the end

应用程序在 waitFor 方法处挂起。

外部应用程序如下所示:

welcome banner

please enter 8 character input:

欢迎横幅使用 printf 打印,输入使用 SetConsoleMode/ReadConsoleInput。 ReadConsoleInput 读取一个字符,它们被 * 字符屏蔽。

帮助

【问题讨论】:

    标签: java external outputstream


    【解决方案1】:

    你可以使用:

    proc.getOutputStream().write("some date".getBytes())
    

    请记住,您必须阅读应用程序发送到 stdout 和 stderr 的所有内容,否则它可能会卡在那里写入。 我使用泛型类在不同的线程中读取它。 用法是这样的:

    InputStreamSucker inSucker = new InputStreamSucker(proc.getInputStream());
    InputStreamSucker errSucker = new InputStreamSucker(proc.getErrorStream());
    proc.waitFor();
    int exit = process.exitValue();
    inSucker.join();
    errSucker.join();
    

    InputStreamSucker 代码在这里:

    public class InputStreamSucker extends Thread
    {
        static Logger logger = Logger.getLogger(InputStreamSucker.class);
    
        private final BufferedInputStream m_in;
    
        private final ByteArrayOutputStream m_out;
    
        private final File m_outFile;
    
        public InputStreamSucker(InputStream in) throws FileNotFoundException
        {
            this(in, null);
        }
    
    
        public InputStreamSucker(InputStream in, File outFile) throws FileNotFoundException
        {
            m_in = new BufferedInputStream(in, 4096);
            m_outFile = outFile;
            m_out = new ByteArrayOutputStream();
            start();
        }
    
        @Override
        public void run()
        {
            try
            {
                int c;
                while ((c = m_in.read()) != -1)
                {
                    m_out.write(c);
                }
            }
            catch (IOException e)
            {
                logger.error("Error pumping stream", e);
            }
            finally
            {
                if (m_in != null)
                {
                    try
                    {
                        m_in.close();
                    } 
                    catch (IOException e)
                    {
                    }
                }
    
                try
                {
                    m_out.close();
                }
                catch (IOException e)
                {
                    logger.error("Error closing out stream", e);
                }
    
                if (m_outFile != null)
                {
                    byte data[] = m_out.toByteArray();
                    if (data.length > 0)
                    {
                        FileOutputStream fo = null;
                        try
                        {
                            fo = new FileOutputStream(m_outFile);
                            fo.write(data);
                        }
                        catch (IOException e)
                        {
                            logger.error("Error writing " + m_outFile);
                        }
                        finally
                        {
                            try
                            {
                                if (fo != null) fo.close();
                            }
                            catch (IOException e)
                            {
                                logger.error("Error closing " + m_outFile);
                            }
                        }
                    }
                }
            }
        }
    
        public String getOutput()
        {
            return new String(m_out.toByteArray());
        }
    }
    

    【讨论】:

    • 欧瑞,顺序重要吗?我应该先读取输入/错误流然后再写入?
    • Omry,谢谢你的代码,我试过了,但它仍然停留在 waitFor。
    • 好吧,如果你的进程正在等待输入,你应该提供它。你可以破解我的代码来打印到 System.out,这样你就会看到你的进程发生了什么。您也可以只跟踪日志文件。确保您使用 proc.getOutputStream().write() 将数据发送到您的进程。
    • Thx Omry,我已经在您的代码中执行了 System.out,并且在读取输出时,至少指出外部应用程序要求我输入值的位置。顺便说一句,当我在应用程序中键入值时,它们使用 * 字符显示,但是当我使用 Java 写入值时我没有看到 - 这可能意味着写入不成功? :(
    • Java 成功读取:欢迎横幅,请输入 8 个字符输入:此时 Java 写入输入,它们应该显示为 * 字符 :-(
    【解决方案2】:

    得到答案!诀窍是使用 WriteConsoleInput() API,因为程序需要键盘事件,而不是文本......这就是 waitFor() 永远等待的原因! :)

    【讨论】:

      猜你喜欢
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-30
      • 2011-11-22
      相关资源
      最近更新 更多