如题,需要实时获取exe程序的输出。如下代码:try 
{
Process pro = Runtime.getRuntime().exec("./test.exe");

BufferedReader br = new BufferedReader(new InputStreamReader(pro.getInputStream()));

String str;
while(( str = br.readLine()) != null)
{
System.out.println(str);
}
} catch (IOException e) 
{
e.printStackTrace();
}
test.exe是一个控制台程序,功能是在控制台一秒输出一行字符。
以上代码获取输出,但是获取不及时,是等所有输出完了,java代码才会打印。不知道是怎么回事?
那位高人解决下。小弟万分感谢。
急等

解决方案 »

  1.   

    你如果需要快的快直接拿inputstream读了输出就可以了
      

  2.   

    因为test.exe没有运行完啊。这个是阻塞的。必须等到test.exe执行完了以后才会执行后面的代码。如果你想达到实际的即时显示的效果。那么可以将test.exe的标准输出重定向到你另一个java程序。然后采用字节流的read方法一个一个读
      

  3.   

    不要用:
      Process pro = Runtime.getRuntime().exec("./test.exe");这个。
    写一个native方法往native层注册一个回调,test.exe每输出一行字符,就调用回调函数。
      

  4.   

    应该把三个表分类才行[cpp] view plaincopyprint?
    01.IENUMITEM  *PortsList;  
    02. // 释放PostsList的辅助函数。当DLL被卸载时调用。   
    03. void freePortsCollection(void)  
    04.  {  
    05.    IENUMITEM *item;  
    06.    item = PortsList;  
    07.    // 有其他元素在列表中吗?   
    08.    while ((item = PortsList))  
    09.    {  
    10.       // 在我们删除这个元素前得到下一个元素   
    11.       PortsList = item->next;  
    12.       // 如果元素的值是一个对象。我们需要对它Relesase()。如果它是一个BSTR,我们需   
    13.       // 要它他SysFreeString()。我们对它调用VariantClear。   
    14.       VariantClear(&item->value);  
    15.       // 释放IENUMITEM   
    16.       GlobalFree(item);  
    17.    }  
    18.  }  
    19. // 初始化我们的Portslist的辅助函数。当DLL第一次被加载时调用   
    20. HRESULT initPortsCollection(void)  
    21.  {  
    22.    IENUMITEM *item;  
    23.    // 添加一个“Port 1”IENUMITEM到我们的列表中   
    24.    if ((PortsList = item =  
    25.        (IENUMITEM *)GlobalAlloc(GMEM_FIXED,  
    26.        sizeof(IENUMITEM))))  
    27.    {  
    28.       item->next = 0;  
    29.       item->value.vt = VT_BSTR;  
    30.       if ((item->value.bstrVal = SysAllocString(L"Port 1")))  
    31.       {  
    32.          // 添加一个“Port 2”IENUMITEM到我们的列表中   
    33.          if ((item->next = (IENUMITEM *)GlobalAlloc(GMEM_FIXED,sizeof(IENUMITEM))))  
    34.          {  
    35.              item = item->next;  
    36.              item->value.vt = VT_BSTR;  
    37.              if ((item->value.bstrVal =SysAllocString(L"Port 2")))  
    38.              {  
    39.                 // 添加一个“Port 3”IENUMITEM到我们的列表中   
    40.                 if ((item->next =(IENUMITEM *)GlobalAlloc(GMEM_FIXED, sizeof(IENUMITEM))))  
    41.                 {  
    42.                    item = item->next;  
    43.                    item->next = 0;  
    44.                    item->value.vt =VT_BSTR;  
    45.                    if((item->value.bstrVal =  
    46.                        SysAllocString(L"Port 3")))  
    47.                       return(S_OK);  
    48.                 }  
    49.              }  
    50.          }  
    51.       }  
    52.    }  
    53.    // 错误   
    54.    freePortsCollection();  
    55.    return(E_FAIL);  
    56.  }  
      IENUMITEM  *PortsList;
       // 释放PostsList的辅助函数。当DLL被卸载时调用。
       void freePortsCollection(void)
        {
          IENUMITEM *item;
          item = PortsList;
          // 有其他元素在列表中吗?
          while ((item = PortsList))
          {
             // 在我们删除这个元素前得到下一个元素
             PortsList = item->next;
             // 如果元素的值是一个对象。我们需要对它Relesase()。如果它是一个BSTR,我们需
             // 要它他SysFreeString()。我们对它调用VariantClear。
             VariantClear(&item->value);
             // 释放IENUMITEM
             GlobalFree(item);
          }
        }
       // 初始化我们的Portslist的辅助函数。当DLL第一次被加载时调用
       HRESULT initPortsCollection(void)
        {
          IENUMITEM *item;
          // 添加一个“Port 1”IENUMITEM到我们的列表中
          if ((PortsList = item =
              (IENUMITEM *)GlobalAlloc(GMEM_FIXED,
              sizeof(IENUMITEM))))
          {
             item->next = 0;
             item->value.vt = VT_BSTR;
             if ((item->value.bstrVal = SysAllWWW.xnmz.comocString(L"Port 1")))
             {
                // 添加一个“Port 2”IENUMITEM到我们的列表中
                if ((item->next = (IENUMITEM *)GlobalAlloc(GMEM_FIXED,sizeof(IENUMITEM))))
                {
                    item = item->next;
                    item->value.vt = VT_BSTR;
                    if ((item->value.bstrVal =SysAllocString(L"Port 2")))
                    {
                       // 添加一个“Port 3”IENUMITEM到我们的列表中
                       if ((item->next =(IENUMITEM *)GlobalAlloc(GMEM_FIXED, sizeof(IENUMITEM))))
                       {
                          item = item->next;
                          item->next = 0;
                          item->value.vt =VT_BSTR;
                          if((item->value.bstrVal =
                              SysAllocString(L"Port 3")))
                             return(S_OK);
                       }
                    }
                }
             }
          }
          // 错误
          freePortsCollection();
          return(E_FAIL);
        }
         我们还得加第二个名为CollectonTypeInfo的全局变量来为我们的ICollection保存一个ITypeInfo…嗯,IDispatch对象。(我们稍后讨论为什么需要这个)。因此我们需要加全局变量,于是我们写两个辅助函数-一个把这个变量初始化为零,另一个来Release这个ITypeInfo:
    [cpp] view plaincopyprint?
    01.// 我们的Icoolection的ITypeInfo。我们只需要一个所以我们把它定义为全局的   
    02.  ITypeInfo    *CollectionTypeInfo;  
    03.  // 初始化我们的ICollecton TypeInfo辅助函数   
    04.  void initCollectionTypeInfo(void)  
    05.   {  
    06.     // 我们还没有为我们的ICollection创建ITypeInfo   
    07.     CollectionTypeInfo = 0;  
    08.   }  
    09.  
    10.  // Release()我们的ICollection的TypeInfo的辅助函数。当我们的DLL被卸载时调用它   
    11.  void freeCollectionTypeInfo(void)  
    12.   {  
    13.     if (CollectionTypeInfo)  
    14.         CollectionTypeInfo->lpVtbl->Release(CollectionTypeInfo);  
      

  5.   

    while(( str = br.readLine()) != null)
                {
                    System.out.println(str);
                }读取部分放到一个新的线程里
      

  6.   

    谢谢哈,不过,不知道这么做。没有用过native方法