我有一些代码用于itextsharp合并2个pdf文件。在某处找到它。合并工作正常,但似乎源文件在完成后仍保持使用状态。我想要做的是删除我已合并的第一个文件,该文件通过fileupload上传,并仅保留合并文件。这肯定是进行合并的代码导致文件保持打开状态。我试图删除服务器上的文件,它告诉我IIShelper打开的东西。通过几个小时的工作,我缩小到这个东西。为什么要保留文件?
public static void MergeFiles(string destinationFile, string[] sourceFiles)
{
int f = 0;
// we create a reader for a certain document
PdfReader reader = new PdfReader(sourceFiles[f]);
// we retrieve the total number of pages
int n = reader.NumberOfPages;
// step 1: creation of a document-object
Document document = new Document(reader.GetPageSizeWithRotation(1));
// step 2: we create a writer that listens to the document
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
// step 3: we open the document
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
if(reader.IsEncrypted() == false)
{
// step 4: we add content
while (f < sourceFiles.Length)
{
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
f++;
if (f < sourceFiles.Length)
{
reader = new PdfReader(sourceFiles[f]);
// we retrieve the total number of pages
n = reader.NumberOfPages;
}
}
}
else
{
//is encrypted
}
// step 5: we close the document
document.Close();
reader.Close();
reader.Dispose();
}
提前致谢
你最后只关闭一个reader
,但每个文件打开一个阅读器。因此,只有最后一个reader
将被关闭。
你需要先关闭旧读者
reader = new PdfReader(sourceFiles[f]);
好的,这就是我最终的结果。
public static void MergeFiles(string destinationFile, string[] sourceFiles)
{
int f = 0;
// we create a reader for a certain document
//PdfReader reader = new PdfReader(sourceFiles[f]);
PdfReader reader = new PdfReader(new RandomAccessFileOrArray(sourceFiles[f], true), null);
if (reader.IsEncrypted() == false)
{
// we retrieve the total number of pages
int n = reader.NumberOfPages;
// step 1: creation of a document-object
Document document = new Document(reader.GetPageSizeWithRotation(1));
// step 2: we create a writer that listens to the document
using(var destinationFileStream = new FileStream(destinationFile, FileMode.Create))
{
PdfWriter writer = PdfWriter.GetInstance(document, destinationFileStream);
// step 3: we open the document
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
// step 4: we add content
while (f < sourceFiles.Length)
{
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
f++;
if (f < sourceFiles.Length)
{
reader = new PdfReader(sourceFiles[f]);
// we retrieve the total number of pages
n = reader.NumberOfPages;
}
}
//close everything
document.Close();
reader.Close();
destinationFileStream.Close();
}
}
else
{
//is encrypted
reader.Close();
}
}
我尝试了关闭阅读器等的所有可能组合,但似乎无论什么itext保持源文件打开。
诀窍是将PdfReader reader = new PdfReader(sourceFiles [f])更改为PdfReader reader = new PdfReader(new RandomAccessFileOrArray(sourceFiles [f],true),null)。
RandomAccessFileOrArray产生了不同。
我绝不是一个itextsharp专家。有人可以向我解释为什么在这种情况下,这对于释放文件的itext有如此大的影响?
这就是我所做的:我创建了一个列表,列出了我合并的所有文件读者,以便跟踪它们,然后我最后将它们全部关闭。
List<PdfReader> readers = new List<PdfReader>();
try
{
int f = 0;
//PdfReader reader = new PdfReader(sSrcFile[f]);
readers.Add(new PdfReader(sSrcFile[f]));
int n = readers[f].NumberOfPages;
//Response.Write("There are " + n + " pages in the original file.\n");
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
while (f < sSrcFile.Length)
{
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(PageSize.A4);
document.NewPage();
page = writer.GetImportedPage(readers[f], i);
rotation = readers[f].GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, readers[f].GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
//Response.Write("\n Processed page " + i + "\n");
}
f++;
if (f < sSrcFile.Length)
{
readers.Add(new PdfReader(sSrcFile[f]));
n = readers[f].NumberOfPages;
//Response.Write("ff : There are " + n + " pages in the original file.\n");
}
}
//Response.Write(returnLocation);
document.Close();
for (var i = 0; i < readers.Count; i++)
{
readers[i].Close();
}
return returnLocation;
}
catch (Exception e)
{
Response.Write("The error message is: " + e.Message);
return e.Message;
}
我在VB.net中遇到了同样的问题。您需要关闭每个阅读器,pdfDoc和编写器。
Imports iTextSharp.text.pdf
Imports iTextSharp.text
Public Sub MergePDF_File(ByVal fileArray As String(), ByVal outPutPDF As String)
If fileArray Is Nothing OrElse fileArray.Length = 0 Then
Throw New ApplicationException("No file list")
End If
If String.IsNullOrEmpty(outPutPDF) Then
Throw New ApplicationException("Must specify output file")
End If
Dim pdfDoc As iTextSharp.text.Document = Nothing
Dim writer As iTextSharp.text.pdf.PdfCopy = Nothing
For i = 0 To fileArray.Length - 1
Using reader As New iTextSharp.text.pdf.PdfReader(fileArray(i))
If i = 0 Then
pdfDoc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1))
writer = New iTextSharp.text.pdf.PdfCopy(pdfDoc, _
New FileStream(outPutPDF, _
FileMode.OpenOrCreate, _
FileAccess.Write))
pdfDoc.Open()
End If
Dim pageCount As Integer = reader.NumberOfPages
For pg = 1 To pageCount
pdfDoc.SetPageSize(reader.GetPageSizeWithRotation(pg))
pdfDoc.NewPage()
Dim page As iTextSharp.text.pdf.PdfImportedPage = Nothing
page = writer.GetImportedPage(reader, pg)
writer.AddPage(page)
Next
reader.Close()
End Using
Next
pdfDoc.Close()
writer.Close()
End Sub
我注意到的一件事是你没有关闭你正在构建的FileStream对象。由于FileStream类实现了IDisposable,我强烈建议您将代码包装在using块中,以便适当地清理资源。
using(var destinationFileStream = new FileStream(destinationFile, FileMode.Create))
{
PdfWriter writer = PdfWriter.GetInstance(document, destinationFileStream));
// step 3: we open the document
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
if(reader.IsEncrypted() == false)
{
// step 4: we add content
while (f < sourceFiles.Length)
{
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(reader.GetPageSizeWithRotation(i));
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
}
f++;
if (f < sourceFiles.Length)
{
reader = new PdfReader(sourceFiles[f]);
// we retrieve the total number of pages
n = reader.NumberOfPages;
}
}
}
else
{
//is encrypted
}
}