Following the footsteps of @n0nuf, I wrote a batch script to check all PDFs in a specific folder with pdfinfo and push it through cpdf if broken as an attempt to fix them:
@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
Or the same as bash script:
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
Broken PDFs will be moved to a subfolder \bak and the recreated PDFs get the suffix _.pdf (which is not perfect, but good enough for me). NOTE: A recreated PDF contains lesser errors and should be viewable with a regular PDF viewer. But this does not mean you get all your content back. Unrecoverable content leads to empty pages.
I also tried the same with JHOVE (Open source file format identification, validation & characterization tool) as suggested by @kraftydevil here: Check if PDF files are corrupted using command line on Linux and can now confirm this is also a valid approach.
(First I had lesser success. But then I noticed I had not handled the output of JHOVE correctly.)
To test both approaches I deleted and altered random parts from a PDF with a text editor (removed streams, so pages failed to render in my PDF viewer, altered PDF Tags, and shifted some bits). The result is: Both pdfinfo and JHOVE are able to spot damaged files correctly (JHOVE was even more sensitive in some cases).
And here is the equivalent script for 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