Reputation: 208
I've searched far and wide for an answer to this question. I know WHY I'm received the exception, but I can't for the life of find the cause of it in my code.
Basically, my code creates four separate PDF files, joins them into on big PDF file and then deletes the original four files. Everything words fine, except I receive an IOException when trying to delete the files because they are 'being used by another process.'
Here is the code I use to merge the files:
private static Document MergeFiles(string[] fileNames, string finalFileName)
{
Document doc = new Document(PageSize.A4, 20, 20, 25, 25);
if (fileNames.Length > 0)
{
int a = 0;
PdfReader reader = new PdfReader(fileNames[a]);
int n = reader.NumberOfPages;
FileStream output = new FileStream("C:\\temp\\" + finalFileName, FileMode.Create);
PdfWriter writer = PdfWriter.GetInstance(doc, output);
doc.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
while (a < fileNames.Length)
{
int i = 0;
while (i < n)
{
i++;
doc.SetPageSize(reader.GetPageSizeWithRotation(i));
doc.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);
}
a++;
if (a < fileNames.Length)
{
reader = new PdfReader(fileNames[a]);
n = reader.NumberOfPages;
}
}
}
doc.Close();
return doc;
}
And here is the code for deleting the files:
private static void DeleteFile(string[] fileNames)
{
if (fileNames != null)
{
for (int x = 0; x < fileNames.Length; x++)
{
if(!fileNames[x].Equals(""))
System.IO.File.Delete(fileNames[x]);
}
}
}
Any assistance would be greatly appreciated. I presume somewhere in the loop when I'm merging the documents, something isn't being closed (reader/writer) but I've tried lots of different combos and nothing seems to work. It's REALLY starting to annoy me.
UPDATE Thanks for your comments, everyone. I've amended my code to this:
private static Document MergeFiles(string[] fileNames, string finalFileName)
{
Document doc = new Document(PageSize.A4, 20, 20, 25, 25);
if (fileNames.Length > 0)
{
while (a < fileNames.Length)
{
using (PdfReader reader = new PdfReader(fileNames[a]))
using (FileStream output = new FileStream("C:\\temp\\" + finalFileName, FileMode.Create))
using (PdfWriter writer = PdfWriter.GetInstance(doc, output))
{
int n = reader.NumberOfPages;
doc.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
int i = 0;
while (i < n)
{
i++;
doc.SetPageSize(reader.GetPageSizeWithRotation(i));
doc.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);
}
a++;
if (a < fileNames.Length)
{
n = reader.NumberOfPages;
}
}
}
}
doc.Close();
return doc;
}
It compiles, but I get an error at runtime which points to the closing brace of the Using loop:
System.ObjectDisposedException was unhandled
Message=Cannot access a closed file.
Upvotes: 1
Views: 6072
Reputation: 122654
You're not disposing any of your resources.
PdfReader
, PdfWriter
, and FileStream
all implement IDisposable
. These all need to either be Dispose
d or wrapped in a using
block (preferably the latter).
My guess is it's the PdfReader
instances that are holding those files open.
P.S. It's not enough to just Close
them at the end of the method, as that will leave them open "permanently" (or as long as the process runs) if any exceptions occur before those calls execute. Either put your cleanup in a finally
block or just use using
.
Upvotes: 4
Reputation: 65
Although you're closing the document (doc.Close();
), you're not closing the filestream, writer and reader.
Add this after doc.Close();
:
writer.Close();
output.Close();
reader.Close();
Upvotes: 0