4
votes

I am using crystal report (run-time version 13.0.15) to generate PDF reports from an asp.net web application. Randomly while using the reports, I am getting a show stopper file-locked error- "System.IO.IOException-The file exists. ", after that none of my reports are not working. But the application was working fine. I did an IIS Reset, but the issue exists.

Then I removed the temp files from "C:\Windows\Temp" folder and then all all reports are working fine.

Here is the source code, I am using to generate reports. I am not using CR viewer. All reports are exporting to PDF.

var __reportData = GetData(filter);
ReportDocument rd = new ReportDocument();
try
{
rd.Load(rptFilePath);
rd.SetDataSource((System.Data.DataTable)__reportData);
System.IO.Stream oStream = null;
byte[] byteArray = null;
oStream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
byteArray = new byte[oStream.Length];
oStream.Read(byteArray, 0, Convert.ToInt32(oStream.Length - 1));
rd.Close();
rd.Dispose();
rd = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
catch (Exception ex)
{
    if (rd != null)
    {
        rd.Close();
        rd.Dispose();
        rd = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }
    CrystalReportExceptionHandler.ShowError(ex, ex.Message);
}
finally
{
    if (rd != null)
    {
        rd.Close();
        rd.Dispose();
        rd = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
        GC.Collect();
    }
}
3

3 Answers

3
votes

This exception is documented in .NET and is raised when the temp directory reaches the limit of 65535 files.

Azure Github example/link

0
votes

See if problem goes away by changing this line of code:

rd.Load(rptFilePath);

to

rd.Load(rptFilePath, OpenReportMethod.OpenReportByTempCopy);

The 2nd version ensures a temporary copy of the report is used.

-1
votes

I suggest re-write code with C# using code blocks like this:

var __reportData = GetData(filter);
using(ReportDocument rd = new ReportDocument()) {

 byte[] byteArray = null;
 rd.Load(rptFilePath);
 rd.SetDataSource((System.Data.DataTable)__reportData);

  using(System.IO.Stream oStream oStream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat)) {
    byteArray = new byte[oStream.Length];
    oStream.Read(byteArray, 0, Convert.ToInt32(oStream.Length - 1));
  }
}

With using block there is no need for manually calling .Close or .Dispose methods on disposable object on success or exception. Also, notice System.IO.Stream is wrapped inside using block to ensure it is disposed off which was missing in original source code.