Zip of PDF document doesn't work

16 posts, 0 answers
  1. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 15 Nov 2013 Link to this post

    Hi,

    I'm trying to zip a PDF document but something goes wrong.
    This is the code I use
    MemoryStream compressedStream;
    ZipPackage package;
    MemoryStream sourcestream = new MemoryStream();
     
    RadDocument document = this.CreateDocument(TileViewmodel);
    this.PrepareDocument(document);
    PdfFormatProvider provider = new PdfFormatProvider();
    provider.Export(document, sourcestream);
     
    compressedStream = new MemoryStream();
    package = ZipPackage.Create(compressedStream);
    package.AddStream(sourcestream, "WindowPeristedData");

    Right before I add a PDF file of 7MB, the length of the compressedStream variable is 22 (bytes I think). After the AddStream the size is 142. I don't think that is correct. The sourcestream I add has a lenghth of 7.085.200. You can't zip an 7MB file into a 142 byte file.

    What am I doing wrong?

    Kind regards, 

    Jan Buskens. 
  2. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 19 Nov 2013 Link to this post

    Hello Jan Buskens,

    You are creating a new ZipPackage entry using an empty MemoryStream which is initially have a length of 0bytes and once you call the ZipPakage.Create(compressedStream) its size is changed to 22 bytes. However you are adding the "sourcestream" variable which have a length of 7MB, after adding the sourcestream to the package the size of the package is update and its now 7MB as expected. The compressedStream does not change its value as it is not used to store the ZipPackage in that stream it is only used to create it. If you want to create a zip file out of a stream you could use the following code:
    string zipFilePath = @"C:\Test\Sample.zip";
    using (ZipPackage zipFile = ZipPackage.CreateFile(zipFilePath))
    {
        zipFile.AddStream(sourcestream, "WindowPeristedData");
    }
    Please let us know if you have any other questions. Also if you think that there is a problem in the outputed file could you please attach a sample demonstrating the issue, this will help us reproduce it on our side.

    I hope this information helps.

    Kind regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  3. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 20 Nov 2013 Link to this post

    Hi,

    Thank you for the reply.

    After adding the sourcestream, the size of the package is indeed updated but to 142 bytes. Not to 7MB. I expect a length of 3.000.000 to 4.000.000 bytes. 142 is way to small.

    I don't want to create a zip file. It has to be a stream because I want to save it to a database.

    Kind regards, 

    Jan Buskens. 
  4. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 22 Nov 2013 Link to this post

    Hello Jan Buskens,

    The RadZipLibrary have a separate methods for compressing a stream without creating a ZipPackage. The ZipPackage is used to create a zip files. The approach and methods required to compress a Stream are described in this article.

    I hope this information helps.

    Kind regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  5. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 25 Nov 2013 Link to this post

    Hi,

    This is the code I now have:
    MemoryStream sourcestream = new MemoryStream();
     
    RadDocument document = this.CreateDocument(TileViewmodel);
    this.PrepareDocument(document);
    PdfFormatProvider provider = new PdfFormatProvider();
    provider.Export(document, sourcestream);
     
    ZipOutputStream zipOutputStream = new ZipOutputStream(sourcestream, ZipCompression.Deflate64);

    The sourcestream is +/- 7MB. After the last line, the zipOutpuStream has an UncompressedSize and a CompressedSize of 0 (zero). The length is +/- 7MB.
    The zipOutputstream.BaseStream is also +/- 7MB.

    Kind regards, 

    Jan Buskens. 
  6. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 27 Nov 2013 Link to this post

    Hello Jan Buskens,

    In order to directly compress the RadDocument you need to set the outputStream to be of type ZipOutputStream, like follows:
    var stream = new MemoryStream();
    ZipCompression method = ZipCompression.Deflate64;
    var zipOut = new ZipOutputStream(stream, method);
    ...
    PdfFormatProvider provider = new PdfFormatProvider();
    provider.Export(editor.Document, zipOut);
    doing so the exported document will be directly compressed by the ZipOutputStream.

    I have attached a sample project in which I am compressing a RadDocument using our ZipOutputStream and a normal MemoryStream. You could observe that the file is compressed about twice its size. Also I have demonstrated how to access the UncompressedStreamSize using our ZipInputStream.

    I hope this information helps.

    Kind regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  7. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 29 Nov 2013 Link to this post

    Hi,

    That seems to be working. Thank you.

    Now... I try to load the data back from the database and I have to unzip it. But I'm not sure how to do that.
    What I get back from the database is byte array from the compressed stream. What is the best way to uncompress it?

    This is what I have after the database access:

    byte[] buffer = attr.TblDatAttachment.Attachment;

    I tried to put it in a ZipInputStream but I don't find a way to get to the uncompressed stream. 
    My goal is to do what's in the following code block (replace <<uncompressedBuffer>> with a variable).

    using (Services.TelerikPdfDocument tpd = new Services.TelerikPdfDocument(<<uncompressedBuffer>>, true))
    {
        Doc.PdfDocument = tpd.Document;
    }

    Kind regards, 

    Jan Buskens. 
  8. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 02 Dec 2013 Link to this post

    As a test to see if the compressed stream is useable I try to save the stream to a file.

    byte[] buffer = new byte[zipOut.Length];
    long count = 0;
    zipOut.BaseStream.Position = 0;
    while (count < zipOut.BaseStream.Length)
    {
        buffer[count++] =
            Convert.ToByte(zipOut.BaseStream.ReadByte());
    }
     
    // Open file for reading
    System.IO.FileStream _FileStream =
       new System.IO.FileStream(@"c:\temp\bufferin.zip", System.IO.FileMode.Create,
                                System.IO.FileAccess.Write);
     
    // Writes a block of bytes to this stream using data from
    // a byte array.
    _FileStream.Write(buffer, 0, buffer.Length);
     
    // close file stream
    _FileStream.Close();

    The file is created but I'm unable to unzip it. The file is invalid or damaged.

    I know that there is another way to create zip files but I just want to be sure that the compressed stream is usable. This is not code that will stay in the application.

    Kind regards, 

    Jan Buskens. 
  9. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 03 Dec 2013 Link to this post

    Hello Jan,

    The files you are trying to create as simply putting a ".zip" suffix will never be a valid zip files despite the stream type(ZipOutput or Stream). If you want to create a zip file I would suggest you to use the ZipLibrary API for creating a zip files(I demonstrated the approach in my first reply in the topic).
    As for your question how to access/uncompress a ZipOutputStream, you need to do the following steps:
    1) Create a ZipOutputStream
    var stream = new MemoryStream();
    ZipCompression method = ZipCompression.Deflate64;
    var zipOut = new ZipOutputStream(stream, method);
    2) Write information to the stream
    PdfFormatProvider provider = new PdfFormatProvider();
    provider.Export(newDocument, zipOut);
    3) Reset the position of the BaseStream. When we start to read the stream its position will be at the end of the stream that is why we need to reset it.
    zipOut.BaseStream.Position = 0;
    4) Create a ZipInputStream in order to decompress the information
    ZipInputStream inputStream = new ZipInputStream(zipOut.BaseStream);
    5) Read the ZipInputStream that we have created.
    byte[] bytes = new byte[zipOut.UncompressedSize];
    int numBytesToRead = (int)zipOut.UncompressedSize;
    int numBytesRead = 0;
    while (numBytesToRead > 0)
    {
        int n = inputStream.Read(bytes, numBytesRead, numBytesToRead);
        if (n == 0)
            break;
        numBytesRead += n;
        numBytesToRead -= n;
    }
    6) Write the information to a pdf file
    string zipFilePath = @"C:\Test\Final.pdf";
    using (FileStream fsNew = new FileStream(zipFilePath,FileMode.Create, FileAccess.Write))
    {
        fsNew.Write(bytes, 0, numBytesRead);
    }
    I hope this information helps.

    Kind regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  10. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 11 Dec 2013 Link to this post

    Hi Kiril,

    This is not exactly what I'm looking for.
    I save the compressed stream to the database with the following code:
    byte[] buffer = new byte[zipOut.Length];
    long count = 0;
    zipOut.BaseStream.Position = 0;
    while (count < zipOut.BaseStream.Length)
    {
        buffer[count++] =
            Convert.ToByte(zipOut.BaseStream.ReadByte());
    }
    The buffer variable is save to the database.

    When we get it back from the database we have this:
    byte[] buffer = attr.TblDatAttachment.Attachment;
    So it's the same byte array that we saved. The question is how I get from this byte array to a TelerikPdfDocument. Is this possible?
    I don't want to save it to a file. I have written a viewer where I can visualize a TelerikPdfDocument.

    Kind regards, 

    Jan Buskens.
  11. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 14 Dec 2013 Link to this post

    Hello Jan,

    I am unable to find the class TelerikPdfDocument in our binaries and that is why I don't know if it is possible to create such class instance out of a byte array. Currently our PdfFormatProvider can be used to export a RadCodument to a pdf file, but can't create a RadDocument out of a pdf file.

    I hope this information helps.

    Regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  12. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 16 Dec 2013 Link to this post

    Hi Kiril,

    Sorry. My bad.

    Let me try to explain it better :-)

    What I do first is create a RadDocument from an internal object we use. That document is compressed.
    RadDocument document = this.CreateDocument(TileViewmodel);
    this.PrepareDocument(document);
    PdfFormatProvider provider = new PdfFormatProvider();
    provider.Export(document, zipOut);


    From my compressed stream I create a byte array with following code
    while (count < zipOut.BaseStream.Length)
    {
        buffer[count++] = Convert.ToByte(zipOut.BaseStream.ReadByte());
    }
    That array (buffer[]) is saved to the database.

    When I read it back from the database, I have this same byte array again ofcourse. From this byte array I want to create the RadDocument again. Is that possible?

    Kind regards,

    Jan Buskens.  
  13. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 17 Dec 2013 Link to this post

    Hello Jan,

    Currently our PdfFormatProvider can be used only to export a RadDocument to a pdf file. Its Import functionality is still not  implemented, you could find more information about the import/export of the RadDocument in this article.

    Kind regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  14. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 20 Dec 2013 Link to this post

    Hi Kiril,

    Then we will have to do it differently :-(

    I've been trying to put all the pieces together to create a zip file or a pdf file from what I have saved to the database. And I didn't succeed.

    How can I create a zip file or a pdf file from a byte array that contains the compressed stream?

    byte[] buffer = attr.TblDatAttachment.Attachment;

    Kind regards, 

    Jan Buskens. 
  15. Kiril Vandov
    Admin
    Kiril Vandov avatar
    324 posts

    Posted 23 Dec 2013 Link to this post

    Hello Jan,

    Once you access the buffer of the compressed stream you need to create a ZipInputStream out of it and then decompress its content either to a new stream or directly save it to your hard drive, like follows:
    byte[] buffer = attr.TblDatAttachment.Attachment;
    MemoryStream memoryStream = new MemoryStream(buffer);
    memoryStream.Position = 0;
     ZipInputStream zipInputStream = new ZipInputStream(memoryStream, false);
     using (zipInputStream)
           {
                    using (FileStream fileStream = new FileStream(@"C:\Test\Test.pdf", FileMode.OpenOrCreate))
                    {
                        zipInputStream.CopyTo(fileStream);
                    }
            }
    Doing so will create the pdf file contained in the stream directly to your hard drive.

    I hope this information helps.

    Kind regards,
    Kiril Vandov
    Telerik
    TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
    Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
    Sign up for Free application insights >>
  16. CreoniX
    CreoniX avatar
    28 posts
    Member since:
    Sep 2009

    Posted 24 Dec 2013 Link to this post

    Tx Kiril. Everything is working now. Not exactly the way we planned to, but it's good enough :-)

    Thank you for your time.

    Kind regards, 

    Jan Buskens. 
Back to Top