Xác thực / xác minh tính toàn vẹn của tệp PDF


11

Có công cụ nào tôi có thể chạy trên kho lưu trữ PDF (tất cả các thư mục) và cuối cùng nó liệt kê / xác định các tệp PDF bị hỏng / không hợp lệ không?

Tôi có hàng trăm tệp PDF (liên quan đến tài liệu, v.v.) trên máy tính của mình (máy Windows) và tôi thường xuyên nhận / phải gửi hàng tá tệp PDF qua email. Bây giờ nó là một thói quen bình thường mà PDF tôi nhận hoặc gửi bị hỏng. Điều này đôi khi tạo ra sự cố nghiêm trọng, khi tệp nguồn (ví dụ: tệp Word hoặc tệp Tex bị thiếu / không khả dụng ngay lập tức).

Việc kiểm tra hàng ngàn tệp PDF này là không thể trong thời gian hữu hạn, vì vậy tôi đã tìm kiếm một công cụ mà tôi có thể chạy một lần và nó quét tất cả các tệp PDF (trong thư mục và thư mục con), và cuối cùng tôi nhận được một danh sách các tệp mà tôi nên -tạo nên. Cho đến bây giờ, có vẻ như không có công cụ như vậy.


2
Nếu bạn đang dùng linux, hãy thử pdfinfo. Hãy xem: superuser.com/questions/580887/ Cách
marcwho


Câu trả lời:


6

Khá dễ dàng để kiểm tra xem một tệp PDF có hợp lệ hay không, bằng cách sử dụng PDFtk. Một GUI miễn phí cho PDFtk có sẵn từ PDF Labs . Khi bạn chạy công cụ này, bạn có thể tải bao nhiêu tệp PDF theo ý muốn, từ nhiều thư mục (bằng cách sử dụng nút Thêm tệp), sau đó nó sẽ bắt đầu truy cập các trang trong các tệp PDF này, rất nhanh chóng.

Nếu bất kỳ tệp nào trong số các tệp PDF được chọn không phải là PDF hợp lệ, tiện ích này sẽ hiển thị thông báo về lỗi và sẽ tự động xóa nó khỏi cửa sổ lựa chọn.

Do đó bạn có thể tiết kiệm nhiều giờ bằng cách sử dụng quy trình này với PDFtk. Ngoài ra, nếu bạn có CPU đa lõi, bạn có thể chạy nhiều phiên bản của tiện ích này và gửi hàng trăm tệp PDF trong mỗi phiên bản.

Tôi đang sử dụng phần mềm này từ 1 năm trước và đây là công cụ PDF tiện dụng nhất tôi từng sử dụng.


2
Ngoài ra, bằng cách sử dụng công cụ (pdfinfo.exe) có sẵn từ liên kết được đề cập bởi marcwho, bạn có thể cdvào FolderContainingPDFsvà chạy lệnh sau trong Windows shell và nó sẽ đánh dấu tệp PDF không hợp lệ trong tệp nhật ký: FORFILES /S /M *.pdf /C "cmd /c echo. & echo @path @fname & D:\XPDF_3.04\bin64\pdfinfo.exe @file" 1>text.txt 2>&1
Mubeen Shahid

4

Tôi đã sử dụng "pdfinfo.exe" từ gói xpdfbin-win và cpdf.exe để kiểm tra các tệp PDF xem có bị hỏng không, nhưng không muốn liên quan đến tệp nhị phân nếu không cần thiết.

Tôi đọc được rằng các định dạng PDF mới hơn có một danh mục dữ liệu xml có thể đọc được ở cuối, vì vậy tôi đã mở tệp PDF với các cửa sổ thông thường NOTEPAD.exe và cuộn xuống qua dữ liệu không thể đọc được đến cuối và thấy một số phím có thể đọc được. Tôi chỉ cần một khóa, nhưng đã chọn sử dụng cả CreationDate và ModDate.

Tập lệnh Powershell (PS) sau đây sẽ kiểm tra TẤT CẢ các tệp PDF trong thư mục hiện tại và xuất trạng thái của từng tệp thành tệp văn bản (! RESULTS.log). Mất khoảng 2 phút để chạy nó với 35.000 tệp PDF. Tôi đã cố gắng thêm ý kiến ​​cho những người mới làm quen với PS. Hy vọng điều này sẽ giúp ai đó tiết kiệm thời gian. Có lẽ có một cách tốt hơn để làm điều này, nhưng điều này hoạt động hoàn hảo cho mục đích của tôi và xử lý các lỗi một cách im lặng. Bạn có thể cần xác định các mục sau khi bắt đầu: $ ErrorActionPreference = "SilentlyContinue" nếu bạn thấy lỗi trên màn hình.

Sao chép phần sau vào tệp văn bản và đặt tên thích hợp (ví dụ: CheckPDF.ps1) hoặc mở PS và duyệt đến thư mục chứa tệp PDF để kiểm tra và dán vào bảng điều khiển.

#
# PowerShell v4.0
#
# Get all PDF files in current directory
#
$items = Get-ChildItem | Where-Object {$_.Extension -eq ".pdf"}

$logFile = "!RESULTS.log"
$badCounter = 0
$goodCounter = 0
$msg = "`n`nProcessing " + $items.count + " files... "
Write-Host -nonewline -foregroundcolor Yellow $msg
foreach ($item in $items)
{
    #
    # Suppress error messages
    #
    trap { Write-Output "Error trapped"; continue; }

    #
    # Read raw PDF data
    #
    $pdfText = Get-Content $item -raw

    #
    # Find string (near end of PDF file), if BAD file, ptr will be undefined or 0
    #
    $ptr1 = $pdfText.IndexOf("CreationDate")
    $ptr2 = $pdfText.IndexOf("ModDate")

    #
    # Grab raw dates from file - will ERR if ptr is 0
    #
    try { $cDate = $pdfText.SubString($ptr1, 37); $mDate = $pdfText.SubString($ptr2, 31); }

    #
    # Append filename and bad status to logfile and increment a counter
    # catch block is also where you would rename, move, or delete bad files.
    #
    catch { "*** $item is Broken ***" >> $logFile; $badCounter += 1; continue; }

    #
    # Append filename and good status to logfile
    #
    Write-Output "$item - OK" -EA "Stop" >> $logFile

    #
    # Increment a counter
    #
    $goodCounter += 1
}
#
# Calculate total
#
$totalCounter = $badCounter + $goodCounter

#
# Append 3 blank lines to end of logfile
#
1..3 | %{ Write-Output "" >> $logFile }

#
# Append statistics to end of logfile
#
Write-Output "Total: $totalCounter / BAD: $badCounter / GOOD: $goodCounter" >> $logFile
Write-Output "DONE!`n`n"

3

Theo bước chân của @ n0nuf, tôi đã viết một tập lệnh bó để kiểm tra tất cả các tệp PDF trong một thư mục cụ thể bằng pdfinfo và đẩy nó qua cpdf nếu bị hỏng như một nỗ lực khắc phục chúng:

@ECHO OFF
FOR %%f in (*.PDF) DO (
    echo %%f
    pdfinfo "%%f" 2>&1 | findstr /I "error"  >nul 2>&1
    if not errorlevel 1 (
        echo "bad -> try to fix"
        @cpdf -i %%f -o %%f_.pdf 2>NUL
        mv %%f .\\bak\\%%f
    ) else (
       REM echo good        
    )
)
@ECHO ON

Hoặc giống như tập lệnh bash:

for file in $(find . -iname "*.pdf")
do
    echo "$file"
    pdfinfo "$file" 2>&1 | grep -i 'error' &> /dev/null
    if [ $? == 0 ]; then
       echo "broken -> try to fix"
       cpdf -i "$file" -o "$file"_.pdf
    fi
done

Các tệp PDF bị hỏng sẽ được chuyển đến thư mục con \ bak và các tệp PDF được tạo lại có hậu tố _.pdf (không hoàn hảo, nhưng đủ tốt cho tôi). GHI CHÚ: Một tệp PDF được tạo lại chứa các lỗi ít hơn và có thể xem được bằng trình xem PDF thông thường. Nhưng điều này không có nghĩa là bạn lấy lại tất cả nội dung của mình. Nội dung không thể phục hồi dẫn đến các trang trống.

Tôi cũng đã thử tương tự với JHOVE (công cụ nhận dạng, xác thực & xác định định dạng tệp nguồn mở) như được đề xuất bởi @kraftydevil tại đây: Kiểm tra xem các tệp PDF có bị hỏng khi sử dụng dòng lệnh trên Linux hay không và bây giờ có thể xác nhận đây cũng là một cách tiếp cận hợp lệ. (Đầu tiên tôi đã thành công ít hơn. Nhưng sau đó tôi nhận thấy tôi đã không xử lý chính xác đầu ra của JHOVE.)

Để kiểm tra cả hai cách tiếp cận, tôi đã xóa và thay đổi các phần ngẫu nhiên từ PDF bằng trình chỉnh sửa văn bản (đã xóa các luồng, do đó các trang không thể hiển thị trong trình xem PDF của tôi, Thẻ PDF đã thay đổi và thay đổi một số bit). Kết quả là: Cả pdfinfo và JHOVE đều có thể phát hiện ra các tệp bị hỏng một cách chính xác (trong một số trường hợp, JHISE thậm chí còn nhạy hơn).

Và đây là kịch bản tương đương cho JHOVE:

@ECHO OFF
FOR %%f in (*.PDF) DO (
    echo %%f
    "C:\Program Files (x86)\JHOVE\jhove.bat" -m pdf-hul %%f | findstr /C:"Well-Formed and valid" >nul 2>&1
    if not errorlevel 1 (
        echo good
    ) else (
        echo "bad -> try to fix"
        @cpdf -i %%f -o %%f_.pdf 2>NUL
        REM mv %%f .\\bak\\%%f
    )
)
@ECHO ON


Cảm ơn bạn @Scott. Vòng lặp FOR-loop của Windows tiết kiệm hơn nhiều tôi đoán. Tôi đã cho việc thực hiện tập lệnh bash giống như một mẫu.
wp78de

Dường như cũng là con đường dành cho Linux: stackoverflow.com/a/9612232/8291949
wp78de
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.