需求来源
Java老师布置了很多实验题,需要同学们将每个实验题的运行结果截图下来。如果是编译问题也需要保存。(每个实验题都是以Example*.java形式的)
我有复制粘贴来的源码,自己手动进行一个一个的截图比较简单。但是能不能用程序帮我自动截图呢?
CompileAndRunAndImage
/**
* 编译、运行当前目录下的src文件夹中的所有Example*.java文件,将结果保存为图片
*/
public class CompileAndRunAndImage {
private static String fatherPath = "src";
private static Runtime runtime = Runtime.getRuntime();
private static List list = new ArrayList();
public static void main(String[] args) throws IOException, Exception {
// 获取当前路径下的src目录
File source = new File(fatherPath);
// 将fatherPah转换成绝对路径备用
fatherPath = source.getAbsolutePath();
// 先编译
iterate(source, 0);
// 再执行
iterate(source, 1);
}
// 递归遍历目录
private static void iterate(File sourceFile, int flag) throws IOException, Exception {
// 判断源文件对象类型
if (sourceFile.isFile()) {
if (flag == 0) {
// 编译
compileFile(sourceFile);
} else if (flag == 1) {
// 运行
runFile(sourceFile);
}
} else {
File[] files = sourceFile.listFiles();
for (int i = 0; i < files.length; i++) {
iterate(files[i], flag);
}
}
}
// 编译文件
private static void compileFile(File file) throws IOException, Exception {
// 得到当前文件的相对路径
String path = file.getAbsolutePath().replace(fatherPath, "");
if (path.startsWith("\\"))
path = path.substring(1);
// 只编译.java文件
if (path.endsWith(".java")) {
System.out.println("javac -encoding UTF-8 " + path);
// list中存储的是文字转图片的文字部分
list.add("javac -encoding UTF-8 " + path);
list.add(" ");
// 得到图片的绝对路径,这里保存的是编译错误的情况时
String imgPath = file.getParentFile().getName();
imgPath = imgPath + "/" + file.getName();
imgPath = imgPath.replace(".java", "编译错误");
imgPath += ".jpg";
// 执行编译命令,并打印日志和生成图片
log(runtime.exec("cmd /c cd " + fatherPath + " && javac -encoding UTF-8 " + path), imgPath);
}
}
// 运行文件
private static void runFile(File file) throws IOException, Exception {
// 得到相对路径
String path = file.getAbsolutePath().replace(fatherPath, "");
if (path.startsWith("\\"))
path = path.substring(1);
// 只编译.java文件生成的字节码文件.class
if (path.endsWith(".java")) {
// 得到.class文件的包名
path = path.replace("\\", ".");
path = path.replace("/", "\\.");
// 将.java替换成空字符串,这样执行语句就是 java com.xxx.MyClass
path = path.replace(".java", "");
System.out.println("\n\n\n");
// 存储执行语句到图片中
String msg = "java " + path;
list.add(msg);
list.add(" ");
// 得到图片路径
String imgPath = file.getParentFile().getName();
imgPath = imgPath + "/" + file.getName();
imgPath = imgPath.replace(".java", ".jpg");
// 运行java程序
log(runtime.exec("cmd /c cd " + fatherPath + " && java " + path), imgPath);
}
}
static int image_height = 400;
static int width = 1370;
static int line_height = 34;
static int every_line = 200;
private static void log(Process pc, String imgPath) throws Exception {
// 得到错误信息和正确信息的混合流
SequenceInputStream sis = new SequenceInputStream(pc.getInputStream(), pc.getErrorStream());
// 使用GBK的格式读取信息
InputStreamReader inst = new InputStreamReader(sis, "GBK");
BufferedReader br = new BufferedReader(inst);
String line;
while ((line = br.readLine()) != null) {
// 如果执行结果中,有以下字符则不输出图片
if (line.contains("使用了未经检查")) {
list.clear();
return;
}
// 添加图片文字
list.add(line);
System.out.println(line);
}
// 保存图片路径中有Example字样的图片
// 也就是说,只保存Example*.java输出的结果为图片
if (imgPath.contains("Example") && list.size() > 2) {
new File(imgPath).mkdirs();
String[] strArr = list.toArray(new String[list.size()]);
createImage(imgPath, strArr, new Font("MicroSoft Yahei", Font.BOLD, 30), width, image_height, every_line,
line_height);
}
list.clear();
// 有些时候,程序可能等待输入,因此这里模仿了键盘输入三次
OutputStream out = pc.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out);
for (int i = 0; i < 3; i++) {
osw.write("over");
}
br.close();
}
// 以下调用的是其他人写的工具类(可换行文字转图片)
// 来源:https://blog.csdn.net/diyangxia/article/details/91956952
public static void createImage(String filePath, String[] strArr, Font font, int width, int image_height,
int every_line, int line_height) throws Exception {
FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(font);
int stringWidth = fm.charWidth('字');// 标点符号也算一个字
//int line_string_num = width % stringWidth == 0 ? (width / stringWidth) : (width / stringWidth) + 1;
int line_string_num = every_line;
System.out.println("每行=" + line_string_num);
List listStr = new ArrayList();
List newList = new ArrayList();
for (int h = 0; h < strArr.length; h++) {
listStr.add(strArr[h]);
}
for (int j = 0; j < listStr.size(); j++) {
if (listStr.get(j).length() > line_string_num) {
newList.add(listStr.get(j).substring(0, line_string_num));
listStr.add(j + 1, listStr.get(j).substring(line_string_num));
listStr.set(j, listStr.get(j).substring(0, line_string_num));
} else {
newList.add(listStr.get(j));
}
}
int a = newList.size();
int b = every_line;
int imgNum = a % b == 0 ? (a / b) : (a / b) + 1;
for (int m = 0; m < imgNum; m++) {
File outFile = new File(filePath);
outFile.createNewFile();
// 创建图片
BufferedImage image = new BufferedImage(width, image_height, BufferedImage.TYPE_INT_BGR);
Graphics g = image.getGraphics();
g.setClip(0, 0, width, image_height);
g.setColor(new Color(240, 218, 210)); // 背景色白色
g.fillRect(0, 0, width, image_height);
g.setColor(Color.black);// 字体颜色黑色
g.setFont(font);// 设置画笔字体
// 每张多少行,当到最后一张时判断是否填充满
for (int i = 0; i < every_line; i++) {
int index = i + m * every_line;
if (newList.size() - 1 >= index) {
System.out.println("每行实际=" + newList.get(index).length());
g.drawString(newList.get(index), 0, line_height * (i + 1));
}
}
g.dispose();
ImageIO.write(image, "jpg", outFile);// 输出png图片
}
}
}