2

いくつかの PDF ファイルを 1 つの PDF ドキュメントに結合したいと考えています。結局のところ、入力ファイルは完全には標準に準拠していません。EOF マーカーの後には、いくつかの追加情報が続きます。

>>
startxref
1994481
%%EOF

%%PPIRoute: 4

明らかに、これによりpyPdfで例外が発生します

pyPdf.utils.PdfReadError: EOF marker not found

ここでの質問は次のとおりです。どうすればよいですか。おそらく、各ファイルを開き、最後の 2 行を削除して保存してから、それらを pyPdf にスローすることができます。しかし、私はその考えがあまり好きではありません。多分そこにもっと良いオプションがありますか?

4

1 に答える 1

3

pdf.py スクリプトread()のクラスのメソッドの先頭を次のように変更することをお勧めします。PdfFileReader

    def read(self, stream):
        # start at the end:
        stream.seek(-1, 2)
        line = ''
        while not line:
            line = self.readNextEndLine(stream)
        if line[:5] != "%%EOF":
            raise utils.PdfReadError, "EOF marker not found"

    ... etc

に:

    def read(self, stream):
        # start at the end:
        stream.seek(-1, 2)
        line = ''
        # read stream backwards while watching for end-of-file marker
        while line[:5] != "%%EOF":
            line = self.readNextEndLine(stream)

    ... etc

私の意見では、元のコードは、Adobe のPDF 1.3 リファレンスドキュメントのセクション 3.4.4「File Trailer」(628 ページ) で暗示されていることを実際には実行していません (イタリック体の鉱山):

Acrobat ビューアは、%%EOF マーカーがファイルの最後の 1024 バイト内のどこかに表示されることのみを必要とします。

言い換えれば、"%%EOF"マーカーの後のファイルの物理的な終わりの前に他のものがあっても問題ありません。私が提案する変更は、これに対応し、例外を発生させるのではなく、マーカーの後にファイルの末尾に追加された可能性のある他のものを無視するようにします (ただし"%%EOF"、最後の 1K バイトにある必要はありません。仕様には記載されていますが、そのチェックを追加することもできます)。これは、マージしようとしているファイルが実際には仕様に準拠している可能性があることも意味します。

アップデート:

"%%EOF"マーカーが最後の 1024 バイト以内にあることも必要とするバージョンを次に示します。

def read(self, stream):
    # start at the end
    stream.seek(-1, os.SEEK_END)
    last1K = stream.tell() - 1024 + 1 # offset of last 1024 bytes of stream

    # read stream backwards while watching for end-of-file marker
    line = ''
    while line[:5] != "%%EOF":
        line = self.readNextEndLine(stream)
        if stream.tell() < last1K:
            raise utils.PdfReadError, "EOF marker not found"

    ... etc
于 2013-03-02T19:52:53.440 に答える