码迷,mamicode.com
首页 > 编程语言 > 详细

BufferedWriter.write()与BufferedReader.readLine() (附带Java中的Runtime exec)

时间:2016-07-15 21:16:32      阅读:321      评论:0      收藏:0      [点我收藏+]

标签:

昨天在实现一个Java程序启动执行C++程序中,遇到了一些问题,先准备把它记录下来(利人利己技术分享


准备实现的测试功能是这样的:在一个java程序中启动一个C++可执行程序,然后java程序和C++程序相互通信(java端发送消息给C++程序处理,C++处理完成后将返回一个结果消息给java程序。不断往返循环直至输入exit指令结束)。


首先,在一个java程序中启动一个C++可执行程序 使用的是java的Runtime.getRuntime().exec()Process类exec()官方说明 http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html 

【另外,还有一种java的JNI (Java Native Interface)框架可以实现java调用其它编程语言的方法】

*说明*: 

使用exec()方式,C++程序的所有标准 io(即 stdinstdout stderr)操作都将通过三个流(getOutputStream()getInputStream() getErrorStream()) 重定向到父进程

因此,使用上述重定向特性就可以通过标准输入输出实现Java与C++程序间的简单通信,在处理通信I/O时,使用了BufferedReader和BufferedWriter作为通信输入输出的缓冲,方便对消息处理。


关于readLine(),此处有篇博文点击打开链接 http://blog.csdn.net/swingline/article/details/5357581


*注意*:

1. 由于C++端是按行读取消息的,所以在Java端发送消息时要注意每个消息的结尾都必须加上换行符。这就是为何我在writeToCpp.write(wstr+"\n"); 中要+"\n"的原因。(就是因为这个换行符没加导致我调bug费了好长时间,之前一直找不出什么原因导致java端在console中输入消息发送后java程序就跑飞了。。后来发现在eclipseconsole中输入字符串回车后该字符串末尾是不带换行符的。。。)


2. 下面的java代码中开辟了一个线程来处理从C++端传送来的消息打印。非常好用!

3. 【引用自点击打开链接

  • 误以为readLine()是读取到没有数据时就返回null(因为其它read方法当读到没有数据时返回-1),而实际上readLine()是一个阻塞函数当没有数据读取时,就一直会阻塞在那,而不是返回null;因为readLine()阻塞后,System.out.println(message)这句根本就不会执行到,所以在接收端就不会有东西输出。要想执行到System.out.println(message),一个办法是发送完数据后就关掉流,这样readLine()结束阻塞状态,而能够得到正确的结果,但显然不能传一行就关一次数据流;另外一个办法是把System.out.println(message)放到while循环体内就可以。

另外有个问题没解决

针对Java启动C++程序场景,如何配置使用eclipse和visual studio (2013)使得我能够从eclipse中debug Java程序跟踪到C++程序后能在Visual studio中继续能debug呢?

我查了下,好像可以通过Visual studio的attach to process功能能够实现联调(在VS中依次打开Debug -> Attach to process. 然后找到启动的java进程选中确定【我选的是javaw.exe】),但是我尝试了好久没有成功。(一开始提示找不到PDB文件,我就去vs的TOOLS -> Options -> Debugging -> Symbols勾选了“Microsoft Symbol Servers” ,部分PDB文件就可以加载了,但还有部分PDB文件加载不上。。。打的断点也是显示黄色圆圈带感叹号 【提示信息见下文】)

还请有经验的大侠能帮忙提供下eclipse与VS联调的解决方案,谢谢!!

下面就是实现了双边通信的java和C++源代码

Java端代码片段:

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Scanner;

public class JavaCallCpp {

			static BufferedWriter writeToCpp;
			static BufferedReader readFromCpp;
	
	public static void main(String[] args) throws IOException {
		
		try {
			Process execute = Runtime.getRuntime().exec("D:/WorkSpace/vs/stringstream/Debug/stringstream");			
			//int exitVal = execute.waitFor();
			writeToCpp = new BufferedWriter(new OutputStreamWriter(execute.getOutputStream()));
			readFromCpp = new BufferedReader(new InputStreamReader(execute.getInputStream()));
			
			MyThread myThread=new MyThread(readFromCpp);
			myThread.start();
			/*Write to C++*/
			writeToCpp.write("have entered the scentence\n");
			writeToCpp.write("aaaaa\n");
			writeToCpp.flush();
			
			//writeToCpp.write("quit\n");
			//writeToCpp.flush();
			/*Read from C++*/
			writeToCpp.write("abcd\n");
			writeToCpp.flush();
			Scanner writer = new Scanner(System.in);
//			while(true){
			String wstr = null;

			while(true){
				
					wstr=writer.next();
					if(wstr.equals("exit")){
						writer.close();
						break;
					}	
					System.out.println(wstr);
					writeToCpp.write(wstr+"\n");
					writeToCpp.flush();
				}
			writeToCpp.flush();
				System.out.println("out of while.");
				/*while((readLine = readFromCpp.readLine()) != null){
					System.out.println(readLine);
				}*/
//			}
			//writerString.close();
			execute.destroyForcibly();//强制终止
			execute.getInputStream().close();
			readFromCpp.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
class MyThread extends Thread{
	private BufferedReader bfr;
	public MyThread(BufferedReader bfr){
		this.bfr=bfr;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		String readLine = null;	
		Boolean _b=true;
		try {
			while(_b){
				readLine=bfr.readLine();
				if(readLine==null)
				{
					_b=false;
				}else{
					System.out.println(readLine);
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}


C++端程序片段:

void fun1(){
	string cmd;
	string line, word;
	cout << "enter a scentence, and exit with typing \"quit\""<<endl;
	while (getline(cin, line)&& line!="quit")
	{
		stringstream stream(line);
		cout << stream.str() << endl;
		while (stream >> word){ cout << word << endl; }
	}

	while (true){
		cout << "please input a command, and exit with typing \"exit\": "<<endl;
		getline(std::cin, cmd);
		if (0==strcmp(cmd.c_str(),"exit")){ //strcmp返回str1-str2的值
			cout << "cmd is exit, exit 0 \n";
			exit (0);
		}
		else if (strcmp(cmd.c_str(), "continue") !=0){
			cout << "cmd is not \"continue\" to break\n";
			continue;
		}
		else{
			cout << "cmd is continue, break while(true) \n";
			break;
		}
	}
	cout << "OK, pass over while(true) \n";
}



/*以下是针对debug问题的(可忽略)*/

eclipse与visual studio联调debug的提示信息

'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\bin\javaw.exe'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\ntdll.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\kernel32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\KernelBase.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\advapi32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\msvcrt.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\sechost.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\rpcrt4.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\user32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\gdi32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\WinSxS\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.10586.0_none_8c15ae12515e1c22\comctl32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\combase.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\bcryptprimitives.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\imm32.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\msvcr100.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\server\jvm.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\psapi.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\wsock32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\ws2_32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\version.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\winmm.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\winmmbase.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\cfgmgr32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\verify.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\java.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\jdwp.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\npt.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\zip.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\shell32.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\windows.storage.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\shlwapi.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\kernel.appcore.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\SHCore.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\powrprof.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\profapi.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Program Files\Java\jdk1.8.0_65\jre\bin\dt_socket.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\NapiNSP.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\pnrpnsp.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\nlaapi.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\mswsock.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\dnsapi.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\nsi.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\winrnr.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\wshbth.dll'. Symbols loaded.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\FWPUCLNT.DLL'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\bcrypt.dll'. Cannot find or open the PDB file.
'javaw.exe' (Win32): Loaded 'C:\Windows\System32\rasadhlp.dll'. Cannot find or open the PDB file.




BufferedWriter.write()与BufferedReader.readLine() (附带Java中的Runtime exec)

标签:

原文地址:http://blog.csdn.net/haifeng_gu/article/details/51916187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!