Save PDF to stream

Hi-
The majority of the PDF files used in my application are scanned drawings or documents.

I am using the following code to save annotations to the PDF files back to the database:

'Create a connection to the database
Dim ConStr As String
ConStr = MyAppConnString
Dim con As New SqlConnection(ConStr)
con.Open()

Dim sqlCommand As New SqlCommand()

’ Set Command text to stored procedure name
With sqlCommand
sqlCommand.Parameters.Clear()
.CommandText = “RetrieveDocument”
’ Set the command type to Stored procedure
.CommandType = CommandType.StoredProcedure
’ Add parameter/s to the command. Depends on the Stored procedure
.Parameters.Add("@SelectedNode", SqlDbType.NVarChar, 128).Value = myTag
'add the conection to the command
.Connection = con
End With

Dim filePath As String = CStr(sqlCommand.ExecuteScalar())

'Obtain a Transaction Context
Dim transaction As SqlTransaction = con.BeginTransaction(“ItemTran”)
sqlCommand.Transaction = transaction

’ Set Command text to stored procedure name
With sqlCommand
sqlCommand.Parameters.Clear()
.CommandText = “tContext”
’ Set the command type to Stored procedure
.CommandType = CommandType.StoredProcedure
.Connection = con
End With

Dim txContext As Byte() = CType(sqlCommand.ExecuteScalar(), Byte())

'Open and read file using SqlFileStream Class
Dim sqlFileStream As New SqlTypes.SqlFileStream(filePath, txContext, FileAccess.ReadWrite)
Dim buffer As Byte() = New Byte(CInt(sqlFileStream.Length)) {}

'Bind the image data to an image control
Dim ms As MemoryStream = New MemoryStream(buffer)

_pdfdoc.Lock()
Try
_pdfdoc.Save(ms, SDF.SDFDoc.SaveOptions.e_incremental)
Catch ex As Exception
MessageBox.Show(ex.ToString(), “Error during the Save”)
End Try
_pdfdoc.Unlock()

sqlFileStream.Write(buffer, 0, buffer.Length)

'Cleanup
sqlFileStream.Close()
sqlCommand.Transaction.Commit()
con.Close()

It seems the above code doesn’t work with many of my PDF files since I receive the following error message after adding an annotation and during the save:
pdftron.Common.PDFNetException: Unknown exception.
at pdftron.PDF.PDFDoc.Save(Stream stm, SaveOptions flags)
at devFacilivuePRO.PDFTron.saveDoc() in [path to file in my project]

The PDF files subsequently seem to become corrupted and cannot be opened (using my application or using the latest version of Adobe Acrobat).

If an error is not received during the save (after adding an annotation), the file cannot be opened by Adobe Acrobat but can be opened in my application.

If I load a good copy of one of the problematic PDF files from the file system in the PDFView sample and save them, the files save without error and can be opened with Adobe Acrobat. Because of this, I’m guessing the problem is not with the PDF files.

Am I doing something wrong while saving?
Thank you,
Matt

It is unclear what you are trying to achieve based on the code snippet you provided. If you wish to load an existing memory stream into a PDFDoc, you can use the PDFDoc’s constructor as it can accept .NET’s System.IO.Stream class (see: http://www.pdftron.com/pdfnet/PDFNetAPIRef/html/M_pdftron_PDF_PDFDoc__ctor_4.htm). For example,

`
Using memStm As New MemoryStream
Using pdfDoc As New PDFDoc(memStm)
pdfDoc.Lock
’ Process pdfDoc here ’
pdfDoc.Unlock
End Using
End Using

`

On the other hand, if you wish to save an existing PDFDoc into a .NET Stream, you will use the Save function like below:

`
Using fileStm As New FileStream(“NewPDF.pdf”, FileMode.CreateNew)
pdfdoc.Save(fileStm, 0);
End Using

`

It seems that you are attempting to write an existing PDFDoc to a stream that is opened via .NET database handles. Perhaps it is better to do it the other way around. Save the PDFDoc to a Stream first, then write the Stream to your database after.

Thanks for looking. The code snippet I provided is my save function that is on the same form as my PDF control. Sorry for any confusion.

After viewing a PDF file and adding an annotation to it, the save function can be invoked, where I’m opening a connection to the database and opening the specific PDF file with ReadWrite access.

The PDF file is opened only with Read access while viewing it.

The database connection and sqlFileStream are closed after the PDF file has been displayed, and my thinking for providing a save option is that the connection and stream need to be opened (with ReadWrite access) to be able to write the changes back to the PDF file and then saved in the database. I was unaware that I could reuse the stream that was used to initially open the file for viewing. Is this the recommended approach?

Ultimately, I want to provide saving annotations to the PDF files, and thought I could simply open the file with ReadWrite access when a save is initiated.

My data is stored in a SQL FileTable.

Hope this clears things up.

You can save on the same .NET Stream object that you opened a PDF document from provided it does not prevent you from doing so (i.e. read/write Streams). You may also need to manually reset the position of your currently opened stream so you can write the changes.

The recommended approach would depend on your use case (i.e. keeping Streams open vs the cost of opening and closing Streams). In the end, nothing in PDFNet though should cause the error you mentioned if it has enough permissions to perform the required operations.

Thanks for the response. I’ll be changing up the way I retrieve the PDF since the current approach isn’t working.