问题来源
最近遇到一个课设,需要用编译原理的知识写一个sql解释器;
整个项目用的是SpringBoot框架,但是不能愉快的白嫖MySql了,
既然需要用sql.exe
,就会在Java中调用它;
select * from tableName
这样的语句就应该作为参数传递到sql.exe中;
从而实现增删改查.
解决思路
实现思路如下:
- Java中调用sql.exe并传入sql语句
- sql.exe执行将结果写入result.txt
- 最后再在Java中读取result.txt中的结果即可
(暂时并未完成sql.exe,只是作为实例来验证方案的可行性)
1. sql.exe的实现(C++)
int main(int argc, char** argv) {
//argv就是传入的sql语句
//增删改查。。。
//将增删改查的结果写入result.txt中(存放CRUD结果)
system("pause");
return 0;
}
2. Java中的调用
String cmd = "C:\\Users\\18655\\Desktop\\sql.exe";//传入的执行文件路径
String sql = "select * from myTable;";//与执行文件路径对应的参数
process = new ProcessBuilder(cmd,sql).start();
测试结果
完整代码
JavaCode
- 方式一
public class Test {
public static void main(String[] args) {
final Runtime runtime = Runtime.getRuntime();
Process process = null;
String cmd = "C:\\Users\\18655\\Desktop\\sql.exe";//传入的执行文件路径
String sql = "select * from myTable;";//与执行文件路径对应的参数
try {
process = new ProcessBuilder(cmd,sql).start();
System.out.println(process.isAlive()); //true
int exitVal = process.waitFor();
System.out.println(exitVal); //0
System.out.println(process.isAlive()); //false
}
catch(Exception e) {
System.out.println(e.getMessage());
}
}
}
- 方式二
public static void main(String[] args) throws IOException, InterruptedException {
String cmd1 = "C:\\Users\\18655\\Desktop\\sql.exe";
String sql = "insert into node(id,name) values(13, lalla);";
String[] command = new String[]{cmd,sql};
BufferedReader br = null;
BufferedReader brError = null;
try {
//执行exe cmd可以为字符串(exe存放路径)也可为数组,调用exe时需要传入参数时,可以传数组调用(参数有顺序要求)
Process p = Runtime.getRuntime().exec(command);
String line = null;
br = new BufferedReader(new InputStreamReader(p.getInputStream()));
brError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = br.readLine()) != null || (line = brError.readLine()) != null) {
//输出exe输出的信息以及错误信息
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
exe源语言(c++)代码
#include<iostream>
#include<vector>
using namespace std;
int main(int argc, char** argv) {
int i;
cout << "\n";
for (i = 1; i < argc; ++i) {
cout << argv[i];
}
FILE* fp = NULL;
errno_t err; //判断此文件流是否存在 存在返回1
err = fopen_s(&fp, "C:\\Users\\18655\\Desktop\\result.txt", "w+"); //若return 1 , 则将指向这个文件的文件流给fp1
fprintf(fp, "This is testing for fprintf...\n");
for (i = 1; i < argc; ++i) {
fputs(argv[i], fp);
fputs("\n", fp);
}
fclose(fp);
system("pause");
return 0;
}