Использование переменной оператора, повторно используемой с PDFSharp

Следующий код использует PDFSharp для разделения страниц PDF-документов на страницы меньше A4 и страницы больше A3:

''' <summary>
''' Process the list of pdfs
''' </summary>
Public Sub ProcessPdfs()

    Dim tempPath As String

    ' Code omitted

    ' Generate a temporary path in case pdfs need to be saved
    If String.IsNullOrEmpty(Me.tempFolder) OrElse Not Directory.Exists(Me.tempFolder) Then
        tempFolder = Path.GetTempPath()
    End If
    tempPath = Path.Combine(Me.tempFolder, Path.GetRandomFileName + ".pdf")

    ' Loop through the pages of the pdfs and process each page in turn. Processing involves
    ' determining the size of the page, then shrinking, adding the footer and then adding to
    ' the appropriate output pdf
    For Each referenceNumber As String In Me.Pdfs.Keys
        For Each pdf As PdfDocument In Me.Pdfs(referenceNumber)
            ' Save the pdf to disk for PDFSharp to be able to read it properly
            If String.IsNullOrEmpty(pdf.FullPath) Then
                pdf.Save(tempPath)
                pdf = PdfReader.Open(tempPath)
            End If
            For Each page As PdfPage In pdf.Pages

                ' Code omitted

                Select Case pageArea
                    Case Is <= a4PageArea
                        Call AddPage(referenceNumber, pdf, page, PageSize.A4)
                    Case Else
                        Call AddPage(referenceNumber, pdf, page, PageSize.A3)
                End Select
            Next
        Next
    Next

    ' Code omitted

    ' Delete temporary pdfs if there are any
    If File.Exists(tempPath) Then
        File.Delete(tempPath)
    End If

End Sub

''' <summary>
''' Add the specified page to the specified output document
''' </summary>
''' <returns>The page which was added to the output pdf</returns>
Private Function AddPage(ByVal ReferenceNumber As String, ByVal ParentPdf As PdfDocument, ByVal ParentPdfPage As PdfPage, ByVal PageSize As PageSize) As PdfPage

    ' Code omitted

    ' Copy the specified page onto thew newly created page
    Using parentForm As XPdfForm = XPdfForm.FromFile(ParentPdf.FullPath)
        parentForm.PageIndex = ParentPdf.Pages.Cast(Of PdfPage)().ToList().IndexOf(ParentPdfPage)
        scaleFactor = 1
        ' Create PdfSharp graphics object with which to write onto the page
        Using graphics As XGraphics = XGraphics.FromPdfPage(outputPdfPage)
            graphics.SmoothingMode = XSmoothingMode.HighQuality

            ' Code omitted

            ' Draw the page
            Call graphics.DrawImage(parentForm, targetRect)
        End Using
    End Using

    Return outputPdfPage

End Function

Что это делает, так это берет PDF-файл, читает страницу esch, а затем масштабирует ее так, чтобы она соответствовала размеру страницы, на которой она должна быть напечатана.

У PDFSharp возникают проблемы с открытием документов, созданных в Adobe v6, поэтому я использую iTextSharp, чтобы восстановить PDF-файл в версии, которую PDFSharp может открыть. Эти PDF-файлы перестраиваются в памяти, и по какой-то причине их необходимо записать на диск, чтобы PDFSharp обработал их правильно.

В ProcessPdfs() я проверяю, есть ли у PDF-файла физический путь, и если нет, я сохраняю его во временном месте.

Проблема, которую я обнаружил, заключается в том, что AddPage(), кажется, постоянно работает с одним и тем же pdf. Я проверил временные pdf-файлы, созданные на диске, и они правильные, т.е. каждый раз разные.

Но файл, загруженный в первом операторе использования XPdfForm.FromFile(ParentPdf.FullPath), никогда не меняется. Как будто код понимает, что путь к файлу не меняется, и поэтому решает не перезагружать файл.

Я думал, что использование оператора using гарантирует, что переменная будет удалена в конце, и поэтому файл будет каждый раз перезагружаться заново. Я неправильно понимаю? Или что здесь происходит?

Кстати, я обошел это, сохранив каждый файл PDF под другим именем файла. Вот почему я думаю, что переменная из используемого блока используется повторно каждый раз на основе имени файла...


person yu_ominae    schedule 01.12.2013    source источник
comment
Нет, переменная не используется повторно. Вполне возможно, что создается новый экземпляр (объект), указывающий на тот же файл на диске.   -  person John Saunders    schedule 01.12.2013
comment
Но тогда все должно быть в порядке, так как на этом этапе файл был перезаписан следующим pdf, верно? Я проверил это, открыв файл вручную между его обработкой. Тем не менее, содержимое имеет правильные размеры страниц, но содержимое каждой страницы соответствует самому первому обработанному PDF-файлу.   -  person yu_ominae    schedule 01.12.2013
comment
Вы можете попробовать явно удалить файл после того, как pdf Sharp завершит работу с ним, но я бы сказал, что другое имя файла для каждого решения, которое у вас есть, проще и, вероятно, быстрее, и вы можете его направить.   -  person Tony Hopkinson    schedule 01.12.2013
comment
Да, в итоге я сохранил каждый файл под другим случайным именем и очистил сразу после его использования (конфиденциальная информация...), и теперь все работает нормально. Я просто не понимаю, почему я должен был это сделать. Как я понимаю, это утверждение using имя файла не должно иметь значения, верно?   -  person yu_ominae    schedule 01.12.2013
comment
Проблема здесь в том, почему он не делает то, что, по моему мнению, должен делать? Я разместил этот вопрос после того, как нашел обходной путь. Я хочу знать, почему мне нужен обходной путь в первую очередь.   -  person yu_ominae    schedule 01.12.2013


Ответы (1)


XPdfForm кэширует документы внутри, и имя файла является ключом. Если вы повторно используете имя файла для нового документа, будет использоваться старый, кэшированный документ.

Кэш является локальным для потока.

Так что это не баг, это фича.

Должна быть возможность использовать потоки вместо файлов.

person I liked the old Stack Overflow    schedule 01.12.2013
comment
Спасибо за ответ. Я думал, что это может быть, но не мог найти это в исходном коде. Хорошо знать. У меня были проблемы с потоками. Он загрузит содержимое, но проигнорирует свойства страницы, как описано в вопросе, который я разместил здесь: using-pdfsharp-workaround-to-open-v6-pdfs" title="проблемы с размером страницы и ориентацией при использовании обходного пути pdfsharp для открытия v6 pdf"> stackoverflow.com/questions/19869739/ Почти уверен, что это неправильное поведение ... - person yu_ominae; 02.12.2013