`
hz_chenwenbiao
  • 浏览: 1010085 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

swftools转换文件时线程堵塞问题的解决方法

阅读更多

 

在使用swftools工具作转换时,最需要注意的是对转换过程中的输入流的处理和出错流的处理。不然,若对流入流(转换过程中会产生的输入流信息有类似如下:NOTICE  processing PDF page 10 (595x842:0:0) (move:0:0)等等的打印时提示信息)处理,那么,转换不能进行下去,线程会堵塞,而不对出错流进行处理,那么当遇到有加密和损坏的文件转换时,也会导致线程的堵塞。对于输入流和出错流的处理,简单处理如下:

 

//注意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 = new	ArrayList<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();
		}
	}
	

 但是这里还是有问题的,因为这里调用process.start方法就开启一个线程进文件进行转换,而若还没开启转换,而线程切换,将文件转换的线程交这里对输入流的线程,那么由br1.readLine()读入的数据就是为null,所以这里的对输入流的处理也就起不了作用就会跳出while循环,而这时又将cpu的使用权交给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 = new	ArrayList<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;
	}

 这里将流入流和出错流作为一个监视线程,两个条件作为跳出循环的判断:

1 输入流处理类:

 

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;
	}
}

 2 出错流处理类:

 

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转换文件而引起的线程堵塞问题。

分享到:
评论
3 楼 梅强强 2016-06-20  
感谢分享。。帮大忙了
2 楼 songjiesdnu 2013-04-15  
楼主你好!非常感谢你的分享~
有一个问题不明白,为什么将对输入流和出错流换成两个类之后就能避免线程切换导致的阻塞问题?
1 楼 hsiunien 2012-08-19  
谢谢 这篇文章对我用处很大,多亏谷歌的智能搜索。。百度太垃圾了。。

相关推荐

    swftools转换工具

    这个强大的工具集可以将多种格式的文件转换为SWF格式,包括字体、图像、PDF文档等,使得这些资源能够在网络上以更高效的方式展示,特别是在Prezi等软件中使用时,能提供流畅且丰富的视觉体验。 一、SWFTools的主要...

    xpdf用来处理swftools将转换pdf中文问题

    为了解决这个中文转换问题,我们可以采用以下步骤: 1. 首先,使用`xpdf` 的 `pdftotext` 工具将包含中文的PDF转换成文本文件,这样可以确保中文字符被正确编码。 ``` pdftotext -enc UTF-8 input.pdf output.txt...

    swftools-0.9.2.rar 将文档转换成swf文件

    SwfTools是一款开源的工具集合,主要用于处理Adobe Flash(SWF)文件,它提供了多种功能,包括PDF到SWF、图像到SWF、XML到SWF等转换。这个"swftools-0.9.2.rar"压缩包包含了SwfTools的0.9.2版本,用于将各种类型的...

    swftools是pdf转swf

    SwfTools作为一个开源项目,为处理SWF和PDF文件提供了强大而灵活的解决方案。通过熟练掌握SwfTools,你可以轻松地创建适合在线阅读的SWF文件,提升网站的用户体验。在不断发展的Web技术中,这样的工具无疑具有很高的...

    swfTools转换工具

    可以把pdf、txt、word、ppt文件转换为swf格式的文件,

    swftools将pdf转换成swf的工具

    SwfTools是一款开源的软件工具集,专门用于处理Adobe PDF文件并将其转换为SWF(ShockWave Flash)格式。这个工具适用于那些希望在Web上分享文档或者创建交互式内容的人们,因为SWF文件通常在网络浏览器中播放效果...

    swftools+openOffice.zip

    《使用SWFTools和OpenOffice实现Office文档到SWF转换》 在数字化信息时代,文件格式的转换成为了日常工作中的常见需求。SWFTools和OpenOffice是两款强大的工具,能够帮助我们方便地将Office文档转换为SWF...

    swftools-0.9.0

    在`Readme-说明.htm`中,通常会包含关于SwfTools 0.9.0的详细安装指南、使用方法、已知问题和解决方法,以及可能的更新日志。安装SwfTools通常涉及解压`swftools-0.9.0.tar.gz`文件,然后按照Readme中的指示编译和...

    swftools-2011-06-23-1815.exe 由dpf转换成swf高清版

    在给定的标题"swftools-2011-06-23-1815.exe 由dpf转换成swf高清版"中,我们看到的是SwfTools的一个特定版本,用于将PDF文件转换为高质量的SWF格式。这个版本发布于2011年6月23日,时间戳为18:15。 SwfTools的核心...

    swftools_i.tar.gz

    9. **XML2SWF**:它能将XML文件转换为SWF,这在创建动态内容时很有用,例如数据驱动的图表或菜单。 10. **SWFTEXT**:一个简单工具,用于创建基于文本的SWF动画,支持基本的文本样式和动画效果。 Swftools的安装...

    swftools工作

    SwfTools是一款开源的软件工具集合,专门用于处理Adobe Flash(SWF)文件。这个工具包提供了多种功能,包括将SWF文件转换为其他格式,提取SWF中的资源,以及创建新的SWF文件。在深入探讨SwfTools之前,我们先来了解...

    linux下swftools安装

    Swftools是一款开源的工具集合,主要用于处理Adobe Flash(SWF)文件,包括转换、合并、提取等多种功能。在Java项目中,如果你使用FlexPaper来实现在线文档阅读,可能会需要用到Swftools来处理SWF文件。然而,...

    linux swftools最新版

    Swftools中的`pdf2swf`工具是其核心功能之一,它能够将PDF文档转换为SWF文件,这在需要在网络上传播或在线阅读PDF时非常有用。通过这个工具,你可以创建体积更小、加载更快的SWF文件,同时保留PDF的原始布局和文本...

    在线展示文档实例c#:FLEXPAPER+SWFTOOLS+office2016+vs15

    这个实例不仅展示了C#与外部工具(如Office和SWFTOOLS)的集成能力,还体现了Web开发中对文件格式转换和在线展示的解决方案。对于开发者来说,理解和掌握这样的技术可以极大地提升工作效率,特别是在处理大量文档时...

    swftools.zip

    SWFTools是一种实用工具与Adobe Flash文件(SWF文件)工作的集合。 该工具集包括用于阅读的SWF文件,结合他们,和他们建立从其他内容(如图像,声音文件,视频或源代码)程序。 SWFTools是在GPL下发布的。 SWFTools ...

    +swftools套件

    Swftools的核心功能之一就是将PDF文档转换为SWF格式,这在需要在网页上展示文档或实现轻量级阅读体验时非常有用。 Flexpaper则是一个流行的在线文档查看和转换解决方案,特别适用于PDF文档。它提供了丰富的功能,如...

    swftools 最新版本 可以说是源码

    SwfTools是一款开源的软件工具集合,主要用于处理Adobe Flash(SWF)文件。这款软件提供了多种功能,包括将PDF转换为SWF、提取SWF中的音频和图像、创建SWF动画以及处理SWF的元数据。SwfTools的最新版本,如描述中...

    openoffice+swftools+flexpaper在线预览文档

    标题 "openoffice+swftools+flexpaper在线预览文档" 涉及到的是一个技术解决方案,用于在Web环境中实现文档的在线预览。这个方案主要包括三个关键组件:OpenOffice、SwfTools和FlexPaper。 1. **OpenOffice**: ...

    FlexPaper+swfTools仿文档在线阅读

    总结来说,"FlexPaper+swfTools仿文档在线阅读"是一种利用Java、OpenOffice、swfTools和FlexPaper等技术,将多种格式的文档转换并以交互式的方式在Web上展示的解决方案。它为用户提供了一个便捷、跨平台的在线阅读...

    Flex在线阅读pdf工具swftools详解

    总结,Swftools是处理SWF文件的强大工具,尤其在将PDF转换为适合Web展示的SWF格式时,它的功能尤为突出。结合Flex,我们可以创建出交互性强、用户体验良好的在线PDF阅读器。在实际应用中,根据具体需求调整Swftools...

Global site tag (gtag.js) - Google Analytics