此代码的主要目标是将PDF文件转换为图像。我还在C:/Media下创建了一个目录,该目录基于PDF名称和当前日期的组合,并将上传的PDF插入到与图像相同的目录中,以便安全保存。
我主要担心的是,我初始化了太多变量和将PDF移动到新创建的目录中的过程过于复杂。我正在寻找关于如何改进这个代码的指导或建议。
public class PdfService {
public static void main(String[] args) {
System.out.println("Test of Convert to PNG");
convertPDFtoImage(args[0]);
}
public static void convertPDFtoImage(String PDFFileName) {
try {
// load PDF document
PDFDocument document = new PDFDocument();
File baseFile = new File(PDFFileName);
document.load(baseFile);
//Get todays date as a String so that you can append it to the directory
String df = new SimpleDateFormat("MM-dd-yy").format(new Date());
//Get the filename without extension so that you can create a directory based on the name
Path path = Paths.get(PDFFileName);
String filenameWithExtension = path.getFileName().toString();
String filename = FilenameUtils.removeExtension(filenameWithExtension);
//add the current date to the filename to get the directory name
String dirname = filename + "-" + df;
//Create the directory
Path dir = Paths.get("C:\\Media\\" + dirname);
Files.createDirectory(dir);
//Move the pdf to the newly created directory
movePDFToDirectory(baseFile, dirname, filenameWithExtension);
// create renderer
SimpleRenderer renderer = new SimpleRenderer();
// set resolution (in DPI)
renderer.setResolution(150);
// render
List<Image> images = renderer.render(document);
// write images to files to disk as JPEG
try {
System.out.println("Begin converting PDF...");
for (int i = 0; i < images.size(); i++) {
ImageIO.write((RenderedImage) images.get(i), "jpeg", new File("C:\\Media\\" + dirname + "\\" + filename + "_" + (i + 1) + ".jpeg"));
}
System.out.println("PDF converted to image(s) successfully.");
} catch (IOException e) {
System.out.println("ERROR: " + e.getMessage());
}
} catch (Exception e) {
System.out.println("ERROR: " + e.getMessage());
}
}
public static void movePDFToDirectory(File originalFile, String directory, String filename) {
InputStream inStream = null;
OutputStream outStream = null;
try{
File newFile = new File("C:\\Media\\" + directory + "\\" + filename);
inStream = new FileInputStream(originalFile);
outStream = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = inStream.read(buffer)) > 0){
outStream.write(buffer, 0, length);
}
inStream.close();
outStream.close();
System.out.println("Original PDF has been copied successfully!");
}catch(IOException e){
e.printStackTrace();
}
}
}备注:
main方法中的一个参数传递。C:/Media)成为一个动态变量。发布于 2014-02-21 17:52:13
+1 @Marc-Andre和其他注释:
movePDFToDirectory:Apache:FileUtils.copyFile(java.io.File, java.io.File)中有类似的方法。幸运的是,它是Ghost4J的一个依赖项,所以它已经在类路径上了,您只需要使用它并删除movePDFToDirectory。Commons是开源的。看到它处理的角落案例很有趣,比如比较destFile.length()和srcFile.length(),以确保所有内容都被正确复制。有效Java,第二版,第47项:了解和使用库(作者只提到JDK的内置库,但我认为其他库也是如此。)ArrayIndexOutOfBoundsException。一个正确的错误信息与预期的参数将是更友好的用户和专业。main方法移动到一个单独的类中。(例如,PdfConverterMain.)将类与其客户端分离通常是一个好主意。ImageIO.write有什么样的参数,他们不必熟悉它,也不必检查API以了解开发人员的意图。参考文献:第6章.编写方法,介绍重构中的解释变量:改进Martin的现有代码设计:将表达式的结果或表达式的一部分放入一个临时变量中,其中包含解释目的的名称。和清洁代码由RobertC.Martin,G19:使用解释性变量。writePage)中,该方法的名称总结了该块的意图,以提高可读性和更容易维护。PDF中的变量和方法名称应该是camelCase,它更容易阅读.在“有效的Java”第二版第56项中有一个很好的段落:坚持普遍接受的命名惯例:大写可能更常见,但有力的论据可以支持只将第一个字母大写:即使连续出现多个首字母缩略词,您仍然可以分辨出一个单词的开头和下一个单词的结尾。您希望看到哪个类名,HTTPURL还是HttpUrl?发布于 2014-02-21 16:42:34
我看到您使用的是Java 7,您可以为所有的IO操作使用try-。它将关闭应用程序中使用的流。
try{
File newFile = new File("C:\\Media\\" + directory + "\\" + filename);
inStream = new FileInputStream(originalFile);
outStream = new FileOutputStream(newFile);
byte[] buffer = new byte[1024];
int length;
//copy the file content in bytes
while ((length = inStream.read(buffer)) > 0){
outStream.write(buffer, 0, length);
}
inStream.close();
outStream.close();
System.out.println("Original PDF has been copied successfully!");
}catch(IOException e){
e.printStackTrace();
}如果有一个IOException,就不会关闭您的流。这可能会在未来的应用中导致一些潜在的问题。要解决这个问题,您可以使用“用资源进行尝试”语法。您的代码看起来可能如下:
File newFile = new File("C:\\Media\\");
try ( InputStream inStream = new FileInputStream(newFile);
OutputStream outStream = new FileOutputStream(newFile);) {
byte[] buffer = new byte[1024];
int length;
// copy the file content in bytes
while ((length = inStream.read(buffer)) > 0) {
outStream.write(buffer, 0, length);
}
System.out.println("Original PDF has been copied successfully!");
} catch (IOException e) {
e.printStackTrace();
}参数名不应以大写字母:public static void convertPDFtoPNG(String PDFFileName)开头。您需要将pdf大写吗?
我会修改你们中的一些评论。注释应该是有帮助的,您不需要重复代码。例子:
// load PDF document
PDFDocument document = new PDFDocument();
File baseFile = new File(PDFFileName);
document.load(baseFile);真的需要//load PDF document吗?您已经在使用document.load了。大多数情况下,一条线性注释只是重复代码中所做的操作。其他读者不需要知道你在做什么,而是知道你为什么要这么做。当我添加评论时,我总是在想:我的代码本身是否足够清晰?我是真的要添加注释,还是可以更改方法名称或变量以更好地表达自己。当代码发生变化时,很难维护注释。
我知道您还没有在生产环境中,但是不要忘记更改所有的e.printStackTrace来进行某种日志记录。
值得知道的是,您可以为您的所有路径使用/,而不是转义\。Java将管理您正在使用的操作系统所需的操作系统。
你是说你把一个PDF转换成一个图像,但这并不完全正确。实际上,您正在将PDF转换为jpeg,这与IMHO完全不同。您很难将创建的图像编码为jpeg,您可能希望在将来进行更改以支持更多的格式。您可能会将图像的编写代码提取到他自己的方法或接口中,以便为每种格式都有多个实现(如果需要的话,我一点也不擅长图像)。
https://codereview.stackexchange.com/questions/42431
复制相似问题