我在Windows上通过python 2.7运行ghostscript,将一堆1页PDF文件转换为TIFF图像。
from os import listdir, remove
from os.path import isfile, join
import ghostscript
import os
import time
import sys
#Assumption #1: The input folder, output_tif_folder and output_pdf_folder
#Assumption #2: Paths in windows use a backslash for reference. They have to be escaped characters - so use a \\ instead of a single \
# eg: 'C:\\Users\\User\\Desktop\\Folder\\'
#Assumption #3: Required libraries are configured and installed properly. They are - i) ghostscript and ii) pyPdf
input_folder = 'C:\\Users\\User\\Desktop\\Folder\\test_files\\'; #Has to be the absolute path, ending with a slash
output_pdf_folder = 'C:\\Users\\User\\Desktop\\Folder\\pdf\\'; #Has to be an absolute path too, ending with a slash
output_tif_folder = 'C:\\Users\\User\\Desktop\\Folder\\tif\\' #Absolute path too, ending with a slash
onlyfiles = [f for f in listdir(input_folder) if isfile(join(input_folder, f))]
from pyPdf import PdfFileWriter, PdfFileReader
for pdfFile in onlyfiles:
inputpdf = PdfFileReader(open(input_folder + pdfFile, 'rb'))
for i in xrange(inputpdf.numPages):
output = PdfFileWriter()
output.addPage(inputpdf.getPage(i))
with open(output_pdf_folder + pdfFile[:-4] + "_%s.pdf" % (i+1), "wb") as outputStream:
output.write(outputStream)
def convertPdfTiff(inputfilename, outputfilename):
args = [
"pdf2tif", # actual value doesn't matter
"-dNOPAUSE", "-dBATCH", "-dSAFER",
"-sDEVICE=tiff24nc",
"-sCompression=pack",
"-sOutputFile=" + outputfilename,
"-f", inputfilename
]
try:
ghostscript.Ghostscript(*args)
except:
print 'something went wrong'
pagefiles = [f for f in listdir(output_pdf_folder) if isfile(join(output_pdf_folder, f))]
for pagefile in pagefiles:
print 'Input: ' + output_pdf_folder + pagefile
print 'Output: ' + output_tif_folder + pagefile[:-4] + ".tif"
convertPdfTiff(output_pdf_folder + pagefile, output_tif_folder + pagefile[:-4] + ".tif")
time.sleep(1)
转换大约114个文件后,我收到以下错误 -
OSError: Too many open files
关于类似问题的其他帖子建议文件描述符应该优雅地关闭,但由于我没有打开它们(我假设ghostscript会这样做),我无法关闭它们。
处理这种情况的最佳方法是什么?
答案 0 :(得分:0)
我不是Python开发人员,但在我看来你正在打开文件(如果我不对,我会道歉):
for pdfFile in onlyfiles:
inputpdf = PdfFileReader(open(input_folder + pdfFile, 'rb'))
我没看到你关闭这些文件的位置。除此之外,Ghostscript肯定应该关闭所有自己的文件,虽然我已经看到Windows花了一些时间来实际关闭文件后GS处理它们。你可以尝试在那里放一个更长的time.sleep(),看看是否有帮助。
当然可以从命令行执行此操作(即直接使用Ghostscript而不是像您看到的那样使用DLL)并处理数百个文件。由于Ghostscript可执行文件使用相同的DLL,因此以这种方式使用它应该没有问题。
答案 1 :(得分:0)
这个问题可能已经解决了,但这是给可能碰到此页面的人的。
您使用
打开文件inputpdf = PdfFileReader(open(input_folder + pdfFile, 'rb'))
行,但是您永远不会像KenS所说的那样关闭这些文件。要解决此问题,请像稍后在第二个with
循环中所做的那样,使用for
语句。
for pdfFile in onlyfiles:
with open(input_folder + pdfFile, 'rb') as inputpdf:
reader = PdfFileReader(inputpdf)
for i in xrange(reader.numPages):
output = PdfFileWriter()
output.addPage(reader.getPage(i))
with open(output_pdf_folder + pdfFile[:-4] + "_%s.pdf" % (i+1), "wb") as outputStream:
output.write(outputStream)
这样,无论什么情况,inputpdf和outputStream都将关闭,因为这就是with
语句的工作方式。即使您在with
语句中遇到异常,该文件也会被关闭。
从这里https://docs.python.org/3/reference/compound_stmts.html#the-with-statement复制:
with语句用于包装具有以下内容的块的执行: 上下文管理器定义的方法(请参见“带语句”部分) 上下文管理器)。这允许常见的
try…except…finally
用法 要封装的样式以方便重用。with_stmt ::= "with" with_item ("," with_item)* ":" suite with_item ::= expression ["as" target]
使用一个“项目”执行with语句的过程如下 如下:
计算上下文表达式(with_item中给出的表达式)以获得上下文管理器。
上下文管理器的
__exit__()
已加载以供以后使用。上下文管理器的
__enter__()
方法被调用。如果with语句中包含目标,则会将
__enter__()
的返回值分配给它。注意:
with语句保证如果
__enter__()
方法返回时没有错误,则将始终调用__exit__()
。 因此,如果在分配给目标列表的过程中发生错误,它将 将被视为与套件内发生的错误相同 是。请参阅下面的步骤6。
该套件已执行。
上下文管理器的
__exit__()
方法被调用。如果异常导致套件退出,则其类型,值和 追溯作为参数传递给__exit__()
。不然三 提供了None
个参数。如果套件由于异常而退出,并且返回值来自
__exit__()
方法为假,则引发异常。如果 返回值是true,抑制了异常,然后执行 继续执行with语句之后的语句。如果套件由于异常以外的其他原因退出,则
__exit__()
的返回值将被忽略,执行将从 所采取的那种出口的正常位置。