I am getting a stream that contains a PDF file and the task is to get that to a browser for the users. I was able to write code to do this with small files, but there are files so big that it can't be stored in the byte array. I wrote a loop to break down the byte array and it comes accross about the right file size, but Adobe Acrobat can't read it and says it's corrupt. I am thinking there must be a way to write the stream directly into the browser. Why do I need to build a byte array to do things like this (all the examples I find use a byte array)? Is there a way to take the stream and just run it directly into the browser?
Here is the code I have. Works as long as the file doesn't exceed the limits of the byte array:
ProtectedSub Page_Load(ByVal senderAsObject,ByVal eAs System.EventArgs)HandlesMe.Load
'This returns the stream fine:
Dim msAs Stream = Test3A()
'Show the file on the web page
Dim bytByteStream()AsByte
ms.Seek(0, SeekOrigin.Begin)
ReDim bytByteStream(CType(ms.Length,Integer) - 1)
ms.Read(bytByteStream, 0,CInt(ms.Length))
Dim countAsInteger = 0
While count < ms.Length
bytByteStream(count) = Convert.ToByte(ms.ReadByte())
'bytByteStream(count) = ms.ReadByte()
count += 1
EndWhile
Dim brAs BinaryReader =New BinaryReader(ms)
Response.AddHeader("Content-Type","application/pdf")
Response.AddHeader("Content-Disposition","inline;filename=def.pdf")
Response.BinaryWrite(bytByteStream)
EndSub
Here is the same code with the do loop to break it down (but returns a file to the browser that Adobe Acrobat can't read: PublicSub test3c(ByVal msAs Stream) 'Show the file on the web page Dim bytByteStream()AsByte Dim intByteIndexAsInteger Response.AddHeader("Content-Type","application/pdf") Response.AddHeader("Content-Disposition","inline;filename=def.pdf") IfCType(ms.Length,Integer) > 65000Then intByteIndex = 65000 Else intByteIndex =CType(ms.Length,Integer) EndIf ms.Seek(0, SeekOrigin.Begin) ReDim bytByteStream(intByteIndex - 1) 'ms.Read(bytByteStream, 0, CInt(ms.Length)) Dim countAsInteger = 0 Dim intPlaceAsInteger = 0 Dim intCyclesAsInteger = 0 While count < ms.Length bytByteStream(intPlace) = Convert.ToByte(ms.ReadByte()) count += 1 intPlace += 1 If intPlace = 65000Then Response.BinaryWrite(bytByteStream)'Writes to the browser intCycles += 1 'Increse the cycle meter IfCType(ms.Length,Integer) - (intCycles * 65000) > 65000Then ReDim bytByteStream(65000)'If we have more than 65K more to go, set up for next chunk Else ReDim bytByteStream(CType(ms.Length,Integer) - (intCycles * 65000))'If less than 65K, then put out whatever we have left EndIf intPlace = 0 'Reset the index placment counter EndIf EndWhile Response.BinaryWrite(bytByteStream)
EndSub
MemoryStream outputStream = ' Construct the stream here...
Response.ClearContent()
Response.ClearHeaders()
Response.ContentType = "application/pdf"
Response.AppendHeader("content-disposition", "inline; filename=PDFFile.PDF")
Response.BinaryWrite(outputStream.ToArray())
outputStream.Close()
Response.End()
NC...
NC,
I see what you are going for and it would be great if it could be simple like what you are doing. However, I am getting a 'stream' from an API which I am passing to the procedure we are working on. Standard 'stream' does not have a "ToArray()" method. Is there a way to convert the stream to a memoryStream? Is there a way around this?
Schu
Try this then:
Dim ms As Stream = Test3A()
Dim outputStream As MemoryStream = CType(ms, MemoryStream)
' Rest of code...
NC...
I get the following error:
Unable to cast object of type 'EMC.Centera.BlobStreams.BlobReadStream' to type 'System.IO.MemoryStream'.
It allowed me to pull it out into a byte array as shown in my earlier code, any other ideas on what would work?
Schu
I have no idea what an 'EMC.Centera.BlobStreams.BlobReadStream' is. I tried the cast with a normal Stream object with no problem, so no, I have no idea.
Did you try:
Dim ms As MemoryStream = Test3A()
NC...
Yes, I know, that is from the API. They claim it is coming out as a simple stream (but obviously if it were we wouldn't have issues). I rewrote the code assumeing it was a memorystream and got the error:
Specified argument was out of the range of valid values.
Parameter name: offset
when I got to the "...(outputStream.ToArray()). Any thoughts?
I was looking through the documentation for this vendor code (sparse) and they mention that the stream is a "blobstream". then it says "that is what your VB code will use to Read - the Stream.Read method."
So, is there a way to convert a blob stream into a memorystream?
Schu
Well, since I have no access to the API that you are using, and all the references to "BlobStream" seem to be Java API related, who can tell? I'd request help from the vendor that created the API as I don't think that you will get much help here.
You know, if you could write the BlobStream thing to a temporary file, this would work:
Dim fileName As String = Server.MapPath("~\Reports\TestPdfFile.pdf")
Response.ClearContent()
Response.ClearHeaders()
Response.ContentType = "application/pdf"
Response.WriteFile(fileName)
Response.Flush()
Response.Close()
NC...
Yea, that's a good idea too. Late last night I got together with a couple of the sr devs here and we came up with the following solution that seems to be working. I rem'd out the code that I had in the earlier post so you can see that all I did was remove a section. Thanks for your help! :)
'Show the file on the web pageDim bytByteStream()AsByte
'ms.Seek(0, SeekOrigin.Begin) ReDim bytByteStream(CType(ms.Length,Integer) - 1) ms.Read(bytByteStream, 0,CInt(ms.Length)) 'Dim count As Integer = 0 'While count < ms.Length ' '>>Following line produces error: ' ' "Value was either too large or too small for an unsigned byte." ' bytByteStream(count) = Convert.ToByte(ms.ReadByte()) ' '>>also tried this which did not work ' ' "Arithmetic operation resulted in an overflow." ' 'bytByteStream(count) = ms.ReadByte() ' count += 1 'End While Response.AddHeader("Content-Type","application/pdf") Response.AddHeader("Content-Disposition","inline;filename=def.pdf")Response.BinaryWrite(bytByteStream)
Well, I was wondering why you seemed to be filling the Byte array and then refilling it in the loop, but I guess I got side-tracked on the MemoryStream thing. Glad you got it.
NC...
0 comments:
Post a Comment