Home Forums .NET libraries Xceed Zip & Real-Time Zip for .NET Zipping from an ASP.NET – A question

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • User (Old forums)
    Member
    Post count: 23064
    #19520 |

    Hi!

    I based my application on a sample given on Martin’s blog:

    <a href=”http://blogs.xceedsoft.com/plantem/PermaLink,guid,e89375a1-63e3-470f-b804-28ef40192554.aspx”>http://blogs.xceedsoft.com/plantem/PermaLink,guid,e89375a1-63e3-470f-b804-28ef40192554.aspx</a&gt;

    This sample desribes basically what i needed, except instead of zipping every file (based on a filter criteria) of one folder, i’d like zip specific files AND rename them. Let me summarize it briefly.

    I have a documentsharing system, and every file gets renamed to a number with a fixed extension when it gets uploaded. Basically, what should happen is, the user checks the files in the list that should get zipped, clicks a button and then receives one zip that contains the checked files, but renamed back to their orignal name. And this has to be done all in memory. The sample above does the trick, but then the zip contains the generated names with the fixed extension. I was wondering if it’s possible to read the files in memory, rename them and then stream them to the zip.

    I tried using <i>DiskFile</i> instead of using <i>DiskFolder</i> as source and add them to the zip by using <i>source.CopyTo(destination, true);</i> but then i get this error:

    Xceed.FileSystem.FileSystemNotSupportedException: The attached stream does not support reading. Type: Xceed.FileSystem.StreamFile FullName: SFF2064:\SF2065

    Imported from legacy forums. Posted by Bert (had 4479 views)

    User (Old forums)
    Member
    Post count: 23064

    Since your ZipArchive is created around a StreamFile, itself created around the Response’s OutputStream, it’s a write-only stream.

    You could change that to create your ZipArchive around a new MemoryFile, then copy that MemoryFile in the StreamFile once each file is renamed, but you would be generating lots of useless rebuilding of the zip file, and use too much memory for nothing.

    What I suggest is using the AbstractFile.CopyTo overloads which takes another AbstractFile as its destination, like this (“destination” is your ZipArchive around the StreamFile):

    <code>
    // Make sure to build the zip file a single time at the very end
    destination.BeginUpdate();

    foreach( AbstractFile file in [[[whatever is your list of selected files]]] )
    {
    AbstractFile destFile = destination.GetFile( file.Name );
    destFile.Name = [[[whatever you want the name in the zip to be]]]

    file.CopyTo( destFile, true );
    }

    // Complete the creation of the zip file. This is the line that
    // will actually write the final zip file in its inner StreamFile.
    destination.EndUpdate();
    </code>

    Hope this helps.

    Imported from legacy forums. Posted by Martin (had 472 views)

    User (Old forums)
    Member
    Post count: 23064

    And I may add that you could replace this:

    <code>
    AbstractFile destFile = destination.GetFile( file.Name );
    destFile.Name = [[[whatever you want the name in the zip to be]]]
    </code>

    By this:

    <code>
    AbstractFile destFile = destination.GetFile( [[[whatever you want the name in the zip to be]]] );
    </code>

    !!!

    Imported from legacy forums. Posted by Martin (had 334 views)

    User (Old forums)
    Member
    Post count: 23064

    Thanks for replying so quickly and accurately Martin.

    There is one problem though. At the moment, I use a hashtable to build up the collection of the files that should get zipped (Key =CurrentFilename (string), Value = OriginalFilename(string)) and then redirect to the aspx page that processes the table and streams the zip.

    The problem i have is that i’m not sure how to create a collection of AbstractFiles from my Hashtable so i can loop through the collection by using the code you provided

    <i>
    foreach( AbstractFile file in [[[whatever is your list of selected files]]] )
    {
    AbstractFile destFile = destination.GetFile( file.Name );
    destFile.Name = [[[whatever you want the name in the zip to be]]]

    file.CopyTo( destFile, true );
    }
    </i>

    I tried creating an AbstractFolder, then looping through the Hashtable and creating an AbstractFile for each entry with the AbstractFolder function <i>CreateFile</i> like this:

    <i>
    Xceed.FileSystem.AbstractFolder aFolder

    foreach (DictionaryEntry de in htZips)
    {
    aFolder.CreateFile(Server.MapPath(getPath() + “/” + Session[“aitsds_dsID”] + “/” + de.Key + “.ds”), false);
    }
    </i>

    and then loop through the created collection like this:

    <i>
    foreach (AbstractFile file in aFolder.GetItems(false))
    {
    AbstractFile destFile = destination.GetFile(file.Name);
    destFile.Name = “test”;
    file.CopyTo(destFile, true);
    }
    </i>

    However, then i get the error of use of unassigned local variable on aFolder, but i can’t call the constructor because it’s an abstract class.

    Do you happen to know how i can easily create a collection of AbstractFiles, purely based on strings that originally come from CheckBoxes so i can loop through the code you provided.

    Imported from legacy forums. Posted by Bert (had 496 views)

    User (Old forums)
    Member
    Post count: 23064

    AbstractFile and AbstractFolder are the base classes. You can’t create them, you create derived classes like DiskFile, DiskFolder, MemoryFile, MemoryFolder, ZippedFile, ZippedFolder, etc.

    If I understand right, your hashtable values contain the original filename on disk, and the destination filename to put in the zip file is the key, right? Then a single loop would do fine. I’d go like this:

    <code>
    foreach( DictionaryEntry de in htZips )
    {
    // This is an existing file on disk you want to zip.
    // I’m assuming de.Value contains the absolute fullname.
    AbstractFile sourceFile = new DiskFile( de.Value );

    // This is where you want to zip the above source file.
    // I’m guessing from your code you want that name to be ‘de.Key’ + “.ds”,
    // without any paths.
    AbstractFile destFile = destination.GetFile( de.Key + “.ds” );

    // Finally, you copy the source over the destination.
    sourceFile.CopyTo( destFile, true );
    }
    </code>

    Imported from legacy forums. Posted by Martin (had 433 views)

    User (Old forums)
    Member
    Post count: 23064

    Thanks for the great support!

    Everything works as it should now. I got a bit confused with how “GetFile” and “CopyTo” really works combined with streaming, i wanted to prevent anything from getting physically written or changed.

    Once again, thanks a bunch!

    Imported from legacy forums. Posted by Bert (had 5285 views)

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.