convert pdf to stream from url

12,751

Solution 1

This will work:

private static Stream ConvertToStream(string fileUrl)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fileUrl);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    try {
        MemoryStream mem = new MemoryStream();
        Stream stream = response.GetResponseStream();

        stream.CopyTo(mem,4096);

        return mem;
    } finally {
        response.Close();
    }
}

However you are entirely responsible for the lifetime of the returned memory stream.

A better approach is:

private static void ConvertToStream(string fileUrl, Stream stream)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fileUrl);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();

    try {
        Stream response_stream = response.GetResponseStream();

        response_stream.CopyTo(stream,4096);
    } finally {
        response.Close();
    }
}

You can then do something like:

using (MemoryStream mem = new MemoryStream()) {
    ConvertToStream('http://www.example.com/',mem);
    mem.Seek(0,SeekOrigin.Begin);

    ... Do something else ...
}

You may also be able to return the response stream directly but you'd have to check on the lifetime of that, releasing the response may release the stream, hence the mem copy.

Solution 2

You may want to take a look at WebClient.DownloadFile.

You give it a URL and local file name and it saves the file straight to disk. Might save you a step or two.

You could also try WebClient.DownloadData which saves the file to an in-memory byte[].

EDIT

You did not specify the protocol of the web-service you are posting the file to. The simplest form (RESTful) would be just to POST the file to data to another URL. Here is how you would do that.

using (WebClient wc = new WebClient())
{
    // copy data to byte[]
    byte[] data = wc.DownloadData("http://somesite.com/your.pdf");

    // POST data to another URL
    wc.Headers.Add("Content-Type","application/pdf");
    wc.UploadData("http://anothersite.com/your.pdf", data);
}

If you are using SOAP, you would have to convert the file to a Base64 string, but hopefully you are using a generated client which takes care of that for you. If you could elaborate on the type of web-service you are sending the file to, I could probably provide some more information..

Share:
12,751
Zaki
Author by

Zaki

Just a coder.

Updated on June 04, 2022

Comments

  • Zaki
    Zaki almost 2 years

    I have a PDF which is hosted in say http://test.com/mypdf.pdf.

    How can I convert the PDF to Stream and then using this Stream convert it back to PDF.

    I tried the following but got an exception(see image):

    private static Stream ConvertToStream(string fileUrl)
    {
        HttpWebResponse aResponse = null;
        try
        {
            HttpWebRequest aRequest = (HttpWebRequest)WebRequest.Create(fileUrl);
            aResponse = (HttpWebResponse)aRequest.GetResponse();
        }
        catch (Exception ex)
        {
    
        }
    
        return aResponse.GetResponseStream();
    }
    

    enter image description here

    • balexandre
      balexandre over 11 years
      what are you trying to do exactly? send a local pdf to the user so he can save? receiving a pdf from user (uploading it) and save to local disk? what exactly?
    • Zaki
      Zaki over 11 years
      basically I get the url of pdf from webservice, send it over to my app, in my app will convert it to stream and send it to another webservice, then in there I am going to read the stream convert back to pdf and save...hope it is not confusing
  • Zaki
    Zaki over 11 years
    I know i can do that but my requirement is not to save it straight as im going to send it to another server.
  • Lloyd
    Lloyd over 11 years
    A utility method on Stream that allows you to copy from one stream to another.
  • Zaki
    Zaki over 11 years
    basically my requirement is to get the url of pdf from webservice, send it over to my app, in my app will convert it to stream and send it to another webservice, then in there I am going to read the stream convert back to pdf and save...hope it is not confusing
  • dana
    dana over 11 years
    Is there anything preventing you from using a byte[]? I think you will want an in-memory buffer anyways if you are not saving anything to disk. Please see my updated answer.
  • Lloyd
    Lloyd over 11 years
    It could be framework dependant. However you can easily write the copy code/extension method yourself. It just reads from one stream and writes to another. You problem is straight forward and you can use my code (with or without CopyFrom), in ...Do something else... you can take mem and pass it on to the web service as needed.
  • Zaki
    Zaki over 11 years
    could you please send a sample of using byte[]
  • Zaki
    Zaki over 11 years
    have tried your method but still get the exception on the above screenshot
  • Lloyd
    Lloyd over 11 years
    Whats the actual exception you get?
  • Zaki
    Zaki over 11 years
    there is not any exception in convert method but the property I am assigning the stream to has this message(btw have made your method to return stream)
  • Lloyd
    Lloyd over 11 years
    Why return a stream? There's no need. If there's an error with the property then that would indicate it's not available. For some stream instances you cannot set position or seek for example, what porperty are you trying to use and why?
  • Zaki
    Zaki over 11 years
    I return it as stream so i can assign it to my property...the property is public Stream PdfStream { get; set; } and once it is converted i return the stream and assign and later on my service (when data is passed to it) take this stream and convert back to pdf...hope that made sense
  • Lloyd
    Lloyd over 11 years
    What you want to do is something like this pastepal.net/view/89f0612b I'm making a few assumptions on how the PDF thing works.
  • Zaki
    Zaki over 11 years
    ok managed to do this but when sending the stream to wcf i get Type 'System.Net.ConnectStream' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.
  • Lloyd
    Lloyd over 11 years
    Ahh yes, Stream isn't serializable. With MemoryStream you can use ToArray() and get a byte[] back and pass that up.
  • Zaki
    Zaki over 11 years
    could you please show me a sample of sending by array or byte
  • dana
    dana over 11 years
    I added some sample code, but am not sure the type of web-service you are sending the file to. Let me know if this helps.
  • Zaki
    Zaki over 11 years
    it is a wcf service and when using the code sample you provided i can see the data having bytes but on transfer to wcf i get this error, could you help please : The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter tempuri.org/:objToSave. The InnerException message was 'There was an error deserializing the object of type System.Collections.Generic.List`1
  • Max Hodges
    Max Hodges over 8 years
    code is incorrect. Stream doesn't not contain a definition for CopyFrom
  • Lloyd
    Lloyd over 8 years
    @MaxHodges You're right it was and has been for quite a while how embarrassing! Resolved now thanks.