swftools转换文件时线程堵塞问题的解决方法
?
//注意destPath最后必须带文件分隔符//这个用来转换的swfTool工具,一但待转换的文件有不可识别的字符在里面时,它就会堵塞在那里。这个情况要处理掉public String PDF2SWF(String sourcePath, String destPath,String fileName) throws Exception {// 目标路径不存在则建立目标路径File dest = new File(destPath);if (!dest.exists()) {dest.mkdirs();}// 源文件不存在则返回File source = new File(sourcePath);if (!source.exists()) {log.info("pdf转换swf失败,源文件不存在!");throw new Exception();}//因为下面进行系统调用,这样就会把系统执行的操作新开启一个线程(在此linux也叫进程),所以它和主扫描程序是独立运行,所以下次还会扫描这个转换中的文件,所以这里要将它设置为不可读,source.setReadable(false);FileConvertUtil fileConvertUtil = new FileConvertUtil();fileName = fileConvertUtil.getFileName(fileName);//获取文件名String outputFile = destPath + fileName + ".swf";log.debug("开始调用swftools转换pdf文件:" + outputFile);List<String> command = newArrayList<String>();command.add(ProjectInit.swftoolsPath);//从配置文件里读取command.add("-z");//command.add("-B");//command.add("rfxview.swf");command.add("-s");command.add("flashversion=9");command.add("-s");command.add("poly2bitmap");//加入poly2bitmap的目的是为了防止出现大文件或图形过多的文件转换时的出错,没有生成swf文件的异常//windows平台下//command.add("languagedir=C:/xpdf/chinese-simplified/");command.add(sourcePath);command.add("-o");command.add(outputFile);ProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command(command);Process process = processBuilder.start();dealWith(process);//处理输入流和出错流try {process.waitFor();//等待子进程的结束,子进程就是系统调用文件转换这个新进程} catch (InterruptedException e) {e.printStackTrace();}log.debug("转换完成!");return outputFile;}private void dealWith(final Process pro){// 下面是处理堵塞的情况try {new Thread(){public void run(){BufferedReader br1 = new BufferedReader(new InputStreamReader(pro.getInputStream()));String text;try {while ( (text = br1.readLine()) != null) {System.out.println(text);}} catch (IOException e) {e.printStackTrace();}}}.start();} catch (Exception e) {e.printStackTrace();}try {new Thread(){public void run(){BufferedReader br2 = new BufferedReader(new InputStreamReader(pro.getErrorStream()));//这定不要忘记处理出理时产生的信息,不然会堵塞不前的String text;try {while( (text = br2.readLine()) != null){System.err.println(text);}} catch (IOException e) {e.printStackTrace();}}}.start();} catch (Exception e) {e.printStackTrace();}}
//注意destPath最后必须带文件分隔符//这个用来转换的swfTool工具,一但待转换的文件有不可识别的字符在里面时,它就会堵塞在那里。这个情况要处理掉public String PDF2SWF(String sourcePath, String destPath,String fileName) throws Exception {// 目标路径不存在则建立目标路径File dest = new File(destPath);if (!dest.exists()) {dest.mkdirs();}// 源文件不存在则返回File source = new File(sourcePath);if (!source.exists()) {log.info("pdf转换swf失败,源文件不存在!");throw new Exception();}//因为下面进行系统调用,这样就会把系统执行的操作新开启一个线程(在此linux也叫进程),所以它和主扫描程序是独立运行,所以下次还会扫描这个转换中的文件,所以这里要将它设置为不可读,source.setReadable(false);FileConvertUtil fileConvertUtil = new FileConvertUtil();fileName = fileConvertUtil.getFileName(fileName);//获取文件名String outputFile = destPath + fileName + ".swf";log.debug("开始调用swftools转换pdf文件:" + outputFile);List<String> command = newArrayList<String>();command.add(ProjectInit.swftoolsPath);//从配置文件里读取command.add("-z");//command.add("-B");//command.add("rfxview.swf");command.add("-s");command.add("flashversion=9");command.add("-s");command.add("poly2bitmap");//加入poly2bitmap的目的是为了防止出现大文件或图形过多的文件转换时的出错,没有生成swf文件的异常//windows平台下//command.add("languagedir=C:/xpdf/chinese-simplified/");command.add(sourcePath);command.add("-o");command.add(outputFile);ProcessBuilder processBuilder = new ProcessBuilder();processBuilder.command(command);Process process = processBuilder.start();//dealWith(process);//改用下面的方式来处理:InputStreamWathThread inputWathThread = new InputStreamWathThread(process);inputWathThread.start();ErrorInputStreamWathThread errorInputWathThread = new ErrorInputStreamWathThread(process);errorInputWathThread.start();try {process.waitFor();//等待子进程的结束,子进程就是系统调用文件转换这个新进程inputWathThread.setOver(true);//转换完,停止流的处理errorInputWathThread.setOver(true);} catch (InterruptedException e) {e.printStackTrace();}log.debug("转换完成");return outputFile;}
import java.io.BufferedReader;import java.io.InputStreamReader;import org.apache.log4j.Logger;//这个类主要用来处理一个系统调用而新创建一个线程或进程执行期间所产生的输入流的处理public class InputStreamWathThread extends Thread {private Process process = null;private boolean over = false;private Logger logger = Logger.getLogger(getClass());public InputStreamWathThread(Process p) {process = p;over = false;}public void run() {try {if (process == null) {logger.info("process为null,无法处理文件转换");return;}//对输入流,可能是一个回车之类的输入BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));while (true) {if (process == null || over) {logger.info("处理完成");break;}String temp;while ((temp = br.readLine()) != null) {//logger.info("输入流信息:" + temp);//如这些信息:NOTICE processing PDF page 10 (595x842:0:0) (move:0:0)等等的打印时提示信息;}}} catch (Exception e) {e.printStackTrace();logger.info("发生异常" + e.getMessage());}}public void setOver(boolean over) {this.over = over;}}
import java.io.BufferedReader;import java.io.InputStreamReader;import org.apache.log4j.Logger;//这个类主要用来处理一个系统调用而新创建一个线程或进程执行期间所产生的出错流的处理public class ErrorInputStreamWathThread extends Thread {private Process process = null;private boolean over = false;private Logger logger = Logger.getLogger(getClass());public ErrorInputStreamWathThread(Process p) {process = p;over = false;}public void run() {try {if (process == null) {logger.info("process为null,无法处理文件转换");return;}//对出错流的处理BufferedReader br = new BufferedReader(new InputStreamReader(process.getErrorStream()));while (true) {if (process == null || over) {logger.info("处理完成");break;}String temp;while ((temp = br.readLine()) != null) {//logger.info("出错流信息:" + temp);;}}} catch (Exception e) {e.printStackTrace();logger.info("发生异常" + e.getMessage());}}public void setOver(boolean over) {this.over = over;}}
这样就可以使用process的执行完毕后通知输入流类和出错流处理类,这样就可以很好的处理调用swftools转换文件而引起的线程堵塞问题。
1 楼 hsiunien 2012-08-19 谢谢 这篇文章对我用处很大,多亏谷歌的智能搜索。。百度太垃圾了。。