BinaryWrite Large Size PDF

D

DBLWizard

Howdy,

I am trying to write code in Visual Basic 6.0 being called from an asp
page. I am trying to write code that allows me to "stream" large size
PDF's. By large size I mean files that are 50MB to 100MB. The reason
to "stream" this is so that the customer does not sit there waiting
for for the PDF to display and thinking there is a problem becuase it
just displays a blank screen until the complete PDF is downloaded.
This code works fine if I do a single BinaryWrite but that again does
not solve the problem. With the code below the file comes down but it
is corrupted. Each page only partially displays. I have played with
it and I can tell that the part of the page that displays is related
to the BUFFER_SIZE. Does anybody see what is wrong with this code?

Thanks

dbl

Private Sub PXCPDF_WriteBuffer(lpPDF_A As Long, sFileNameA As String)
Const BUFFER_SIZE = 20480

Dim lRC As Long
Dim lStreamLength As Long

Set mobjStream = olelib.CreateStreamOnHGlobal(0, True)
lRC = PXC_WriteDocumentToIStream(lpPDF_A, mobjStream)

If (IS_DS_FAILED(lRC)) Then
Exit Sub
End If

Call mobjStream.Stat(mobjStreamStat)
lStreamLength = Currency2Long(mobjStreamStat.cbSize)

Dim lBytesToRead As Long
Dim curBufferPtr As Currency
Dim curReturn As Currency
Dim objResponse As Response

Set objResponse = mobjContext("Response")
lBytesToRead = BUFFER_SIZE
ReDim mabtBuffer(lBytesToRead)
curBufferPtr = 0

objResponse.Buffer = True
objResponse.ContentType = "application/pdf"

objResponse.AddHeader "Content-disposition", _
"inline; filename=" + sFileNameA + "_doc.pdf"

While curBufferPtr < mobjStreamStat.cbSize
If curBufferPtr + Long2Currency(lBytesToRead) >
mobjStreamStat.cbSize Then
lBytesToRead = Currency2Long(mobjStreamStat.cbSize -
curBufferPtr)
End If

ReDim mabtBuffer(lBytesToRead)
curReturn = mobjStream.Seek(curBufferPtr,
olelib.STREAM_SEEK_SET)
lRC = mobjStream.Read(mabtBuffer(0), lBytesToRead)
curBufferPtr = curBufferPtr + Long2Currency(lBytesToRead)
objResponse.BinaryWrite (mabtBuffer)
objResponse.Flush
Wend

objResponse.End

Set objResponse = Nothing
Set mobjStream = Nothing

End Sub
 
E

Evertjan.

DBLWizard wrote on 12 jan 2009 in
microsoft.public.inetserver.asp.general:
I am trying to write code in Visual Basic 6.0 being called from an asp
page. I am trying to write code that allows me to "stream" large size
PDF's. By large size I mean files that are 50MB to 100MB. The reason
to "stream" this is so that the customer does not sit there waiting
for for the PDF to display and thinking there is a problem becuase it
just displays a blank screen until the complete PDF is downloaded.
This code works fine if I do a single BinaryWrite but that again does
not solve the problem. With the code below the file comes down but it
is corrupted. Each page only partially displays. I have played with
it and I can tell that the part of the page that displays is related
to the BUFFER_SIZE. Does anybody see what is wrong with this code?

Why use Visual Basic 6.0, besides being off topic on this NG?

Do a force download with something like:

Response.AddHeader "Content-Disposition", "attachment; filename=" &
strFileName

========================================

function pdf(strFileName)
Response.Clear
strFilePath=server.mappath(strFilename)
Set objStream = Server.CreateObject("ADODB.Stream")
objStream.Open
objStream.Type = 1
objStream.LoadFromFile strFilePath
Response.AddHeader "Content-Disposition", "attachment; filename=" &
strFileName
Response.ContentType = "application/pdf"
Response.BinaryWrite objStream.Read
objStream.Close
Set objStream = Nothing
Response.end
end function

[Not tested as such]
 
A

Anthony Jones

DBLWizard said:
Howdy,

I am trying to write code in Visual Basic 6.0 being called from an asp
page. I am trying to write code that allows me to "stream" large size
PDF's. By large size I mean files that are 50MB to 100MB. The reason
to "stream" this is so that the customer does not sit there waiting
for for the PDF to display and thinking there is a problem becuase it
just displays a blank screen until the complete PDF is downloaded.
This code works fine if I do a single BinaryWrite but that again does
not solve the problem. With the code below the file comes down but it
is corrupted. Each page only partially displays. I have played with
it and I can tell that the part of the page that displays is related
to the BUFFER_SIZE. Does anybody see what is wrong with this code?

Thanks

dbl

Private Sub PXCPDF_WriteBuffer(lpPDF_A As Long, sFileNameA As String)
Const BUFFER_SIZE = 20480

Dim lRC As Long
Dim lStreamLength As Long

Set mobjStream = olelib.CreateStreamOnHGlobal(0, True)
lRC = PXC_WriteDocumentToIStream(lpPDF_A, mobjStream)

If (IS_DS_FAILED(lRC)) Then
Exit Sub
End If

Call mobjStream.Stat(mobjStreamStat)
lStreamLength = Currency2Long(mobjStreamStat.cbSize)

Dim lBytesToRead As Long
Dim curBufferPtr As Currency
Dim curReturn As Currency
Dim objResponse As Response

Set objResponse = mobjContext("Response")
lBytesToRead = BUFFER_SIZE
ReDim mabtBuffer(lBytesToRead)
curBufferPtr = 0

objResponse.Buffer = True
objResponse.ContentType = "application/pdf"

objResponse.AddHeader "Content-disposition", _
"inline; filename=" + sFileNameA + "_doc.pdf"

While curBufferPtr < mobjStreamStat.cbSize
If curBufferPtr + Long2Currency(lBytesToRead) >
mobjStreamStat.cbSize Then
lBytesToRead = Currency2Long(mobjStreamStat.cbSize -
curBufferPtr)
End If

ReDim mabtBuffer(lBytesToRead)
curReturn = mobjStream.Seek(curBufferPtr,
olelib.STREAM_SEEK_SET)
lRC = mobjStream.Read(mabtBuffer(0), lBytesToRead)
curBufferPtr = curBufferPtr + Long2Currency(lBytesToRead)
objResponse.BinaryWrite (mabtBuffer)
objResponse.Flush
Wend

objResponse.End

Set objResponse = Nothing
Set mobjStream = Nothing

End Sub

I take it you've already tried Response.Buffer = false and passed the
Response object directly to WriteDocumentToIStream (the ASP Response object
implements IStream)? IOW let the WriteDocumentToIStream pump the document to
the response for you.

You should get yourself the free HTTP debugger.

http://www.fiddlertool.com/fiddler/

This will let you watch the conversation between client and server.

You've confirmed by some other means that WriteDocumentToIStream is
generating correct content, perhaps by writing to a file stream? You've
confirmed that fetchin said file as an ordinary file.pdf from IIS works as
well?

If so compare in fiddler the fetch to the pdf with the fetch to asp, what
are the differences in received headers and content?
 
D

DBLWizard

I take it you've already tried Response.Buffer = false and passed the
Response object directly to WriteDocumentToIStream (the ASP Response object
implements IStream)? IOW let the WriteDocumentToIStream pump the documentto
the response for you.

You should get yourself the free HTTP debugger.

http://www.fiddlertool.com/fiddler/

This will let you watch the conversation between client and server.

You've confirmed by some other means that WriteDocumentToIStream is
generating correct content, perhaps by writing to a file stream?  You've
confirmed that fetchin said file as an ordinary file.pdf from IIS works as
well?

If so compare in fiddler the fetch to the pdf with the fetch to asp, what
are the differences in received headers and content?

Anthony,

I found the major problem with my code. It has to do with VB and the
way it allocates arrays. When you dim something like ReDim buffer(50)
you actually get 51 elements. The corrupted document problem went
away when I changed the ReDim to be: ReDim abtBuffer(lBytesToRead -
1). But I didn't get the behavior I expected. It still waited until
the complete document had been downloaded before loading the Adobe
interface and displaying any portion of the PDF.

You have my interested peeked but I couldn't get the
WriteDocumentToIStream to work with the Response object. Remember
that I am using VB 6.0 not .Net. Its not by choice believe me but my
customer is not ready to upgrade. I tried passing in the Response
object to the WriteDocumentToIStream but I got a "Subscript out of
range" error. Here is the code that resulted in that error:

Private Sub PXCPDF_WriteBuffer(lpPDF_A As Long, sFileNameA As String)
On Error GoTo errHandler

Const appMethodName = "PXCPDF_WriteBuffer"

Dim lRC As Long

Set objResponse = mobjContext("Response")

objResponse.Buffer = False
objResponse.ContentType = "application/pdf"
objResponse.AddHeader "Content-Disposition", _
"inline;filename=" + sFileNameA + "_doc.pdf"

lRC = PXC_WriteDocumentToIStream(lpPDF_A, objResponse)

If (IS_DS_FAILED(lRC)) Then
Err.Raise lRC, appModuleName & ":" & appMethodName, " Error -
PXC_WriteDocumentToIStream: IS_DS_FAILED(). lRC = " & lRC & " Msg:" &
GetDSErrorString(lRC)
Exit Sub
End If

objResponse.End

Set objResponse = Nothing

Exit Sub

errHandler:
Err.Record appModuleName, appMethodName, errRaise
Exit Sub
Resume
End Sub

I also tried Setting the Response.Buffer to False and writing the
whole buffer at once. When I do that I get a -2147467259 Description:
006~ASP 0251~Response Buffer Limit Exceeded~Execution of the ASP page
caused the Response Buffer to exceed its configured limit. I have set
ASPBufferingOn to False nothing seems to change. I know I could
change buffer limit but that doesn't solve my problem. It just
doesn't seem to actually turn Buffering off.

Any help would be greatly appreciated.

Thanks

dbl
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top