これは、この質問のフォローアップです: here、iText が関係しています。別の回転角度で新しい Pdf を作成し、古いものを削除して、新しいものの名前を古いものの名前に変更します。私の問題が実際に発生することを確認しました(回転== null、wtfの場合のみ)
outFile.renameTo(inFile)
奇妙なことに、renameTo() は true を返しますが、ファイルは元のファイルと等しくないため、Windows の Adobe Reader で outFile が開かなくなります。デスクトップ Pdf 修復プログラムで破損した Pdf ファイルを分析しようとしましたが、得られた結果は次のとおりです。
The end-of-file marker was not found.
The ‘startxref’ keyword or the xref position was not found.
The end-of-file marker was not found.
delete() と renameTo() の呼び出しを省略すると、2 つのファイルが残りますが、どちらも破損していません。また、ファイルの内容を byte[] でコピーしようとしましたが、同じ結果が得られました。inFile は実際には File のサブクラスであり、同じ結果が得られるため、 outFile.renameTo(new File(inFile.toString()) を試しました。同じ結果で new FileDescriptor().sync() を試しました。これを追加しようとしました同じ結果ですべてのファイル操作の間にブロードキャストします。
PdfRotateService.appContext.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri
.parse("file://")));
同じ結果でスレッドをスリープさせてみました。パスが正しいことを確認しました。例外はスローされず、deele() と renameTo() は true を返します。また、FileOutputStream への参照を保持し、finally ブロックで手動で閉じようとしました。
Android OS か何かにバグがあるのではないかと考え始めています (しかし、簡単なことを見落としている可能性があります)。助けてください! オリジナルと同じファイル名の回転された Pdf が必要です。
static boolean rotatePdf(LocalFile inFile, int angle)
{
PdfReader reader = null;
PdfStamper stamper = null;
LocalFile outFile = getGoodFile(inFile, ROTATE_SUFFIX);
boolean worked = true;
try
{
reader = new PdfReader(inFile.toString());
stamper = new PdfStamper(reader, new FileOutputStream(outFile));
int i = FIRST_PAGE;
int l = reader.getNumberOfPages();
for (; i <= l; ++i)
{
int desiredRot = angle;
PdfDictionary pageDict = reader.getPageN(i);
PdfNumber rotation = pageDict.getAsNumber(PdfName.ROTATE);
if (rotation != null)
{
desiredRot += rotation.intValue();
desiredRot %= 360;
}
// else
// worked = false;
pageDict.put(PdfName.ROTATE, new PdfNumber(desiredRot));
}
} catch (IOException e)
{
worked = false;
Log.w("Rotate", "Caught IOException in rotate");
e.printStackTrace();
} catch (DocumentException e)
{
worked = false;
Log.w("Rotate", "Caught DocumentException in rotate");
e.printStackTrace();
} finally
{
boolean z = closeQuietly(stamper);
boolean y = closeQuietly(reader);
if (!(y && z))
worked = false;
}
if (worked)
{
if (!inFile.delete())
worked = false;
if (!outFile.renameTo(inFile))
worked = false;
}
else
{
outFile.delete();
}
return worked;
}
static boolean closeQuietly(Object resource)
{
try
{
if (resource != null)
{
if (resource instanceof PdfReader)
((PdfReader) resource).close();
else if (resource instanceof PdfStamper)
((PdfStamper) resource).close();
else
((Closeable) resource).close();
return true;
}
} catch (Exception ex)
{
Log.w("Exception during Resource.close()", ex);
}
return false;
}
public static LocalFile getGoodFile(LocalFile inFile, String suffix)
{
@SuppressWarnings("unused")
String outString = inFile.getParent() + DIRECTORY_SEPARATOR +
removeExtension(inFile.getName()) + suffix + getExtension(inFile.getName());
LocalFile outFile = new LocalFile(inFile.getParent() + DIRECTORY_SEPARATOR +
removeExtension(inFile.getName()) + suffix + getExtension(inFile.getName()));
int n = 1;
while (outFile.isFile())
{
outFile = new LocalFile(inFile.getParent() + DIRECTORY_SEPARATOR +
removeExtension(inFile.getName()) + suffix + n + getExtension(inFile.getName()));
++n;
}
return outFile;
}