<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Martin Plante</title>
    <link>http://blogs.xceedsoft.com/plantem/</link>
    <description>Open window on development at Xceed </description>
    <language>en-us</language>
    <copyright>Xceed Software Inc.</copyright>
    <lastBuildDate>Wed, 05 Apr 2006 12:43:13 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.8.5223.0</generator>
    <managingEditor>plantem@xceedsoft.com</managingEditor>
    <webMaster>plantem@xceedsoft.com</webMaster>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=b637efea-3f3b-4ed3-84b9-99a588912b33</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,b637efea-3f3b-4ed3-84b9-99a588912b33.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      It's been a long time since I've posted something "chewable". My energies were all
      directed on the soon to be released <a href="http://xceedsoft.com/products/ZipNet/">Xceed
      Zip for .NET</a> version 3.0. Though the apparent changes on the public interface
      are quite minor, and one can teach the new classes quite easily, the underlying code
      wasn't trivial.
   </p>
        <p>
      In short, for all of you who know what ZipArchive, ZippedFile and ZippedFolder are,
      say hello to TarArchive, TarredFile, TarredFolder, GZipArchive and GZippedFile.
   </p>
        <p>
      And when I say "easy to teach", what it really means is "find yourself a zipping example,
      and replace class name occurances of Zip{something} with Tar{somethong} or GZip{something}".
   </p>
        <p>
      Sure, there are some gotchas, like the fact that a GZIP archive cannot contain
      filenames with subfolders, are not well-suited to contain more than one compressed
      file, and can contain files without filenames. But these are details you'll get used
      to quite easily.
   </p>
        <p>
      There are two things that make me really proud in that product. One is under the hood,
      and the other is a sample. First, the engine: My colleague Jacques and I have come
      up with what we call the "Storage Engine". It's an abstraction of what an archiving
      library needs in term of temp storage, in-place archive updating, and transactional
      operations on an archive. Both the new TAR and GZIP implementations use it. In short,
      it abstracts the fact that we want to always update an archive in-place when possible,
      but revert to temp files and make sure to commit those temp files with any existing
      archive upon the last modification of it. If things go well, the ZIP implementation
      will benefit from it sooner than later.
   </p>
        <p>
      Second, the sample: The FTP Sample Explorer is gone, replaced with the FileSystem
      Snippet Explorer, a sample that let's you see, modify and run code snippets that show
      you the various tasks one might wish to implement. It goes straight to the point.
      No bells and whistle, no gravy, just the meat. The code is embedded in the executable
      as compressed serialized XML data. The main information (each topic's description
      and code) is nothing else than rich text. The nice thing about this sample is
      that in order for me to modify and add new topics, I simply need to compile the project
      with an extra define, and I'm now running the application in "admin" mode, enabling
      me to update the compressed XML file directly, for the next compilation to benefit
      from this update.
   </p>
        <p>
      Though I've finished work on this 3.0 version, I already have both hands in the two
      next releases of Xceed Zip for .NET and Xceed FTP for .NET. The first one will add
      support for AES encryption, and the second one will now offer proxy support.
   </p>
        <p>
      I didn't have much time to write because all those releases have a tight schedule
      I can't bust. I'm leaving Xceed in two months. Yup, I've decided it was time for me
      to move on. Until then, I have agreed to complete AES implementation, help Jacques
      kick-start proxy support and train about everybody here, each earning one of the numerous
      hats I'm wearing. It was a very difficult decision, since I have only friends at Xceed.
      Though the nine years or so I've spent here were exciting and challenging, I feel
      it's time for me to try new stuff... by myself. This isn't a divorce. I won't be far
      from Xceed, and still available to help them from time to time. As for you, dear customers
      and readers, rest assured you will stay in good hands. The team behind Xceed Zip and
      Xceed FTP, both .NET and ActiveX, will remain strong, even get stronger than it is
      now.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=b637efea-3f3b-4ed3-84b9-99a588912b33" />
      </body>
      <title>Releases come and go...</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,b637efea-3f3b-4ed3-84b9-99a588912b33.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,b637efea-3f3b-4ed3-84b9-99a588912b33.aspx</link>
      <pubDate>Wed, 05 Apr 2006 12:43:13 GMT</pubDate>
      <description>&lt;p&gt;
   It's been a long time since I've posted something "chewable". My energies were all
   directed on the soon to be released &lt;a href="http://xceedsoft.com/products/ZipNet/"&gt;Xceed
   Zip for .NET&lt;/a&gt; version 3.0. Though the apparent changes on the public interface
   are quite minor, and one can teach the new classes quite easily, the underlying code
   wasn't trivial.
&lt;/p&gt;
&lt;p&gt;
   In short, for all of you who know what ZipArchive, ZippedFile and ZippedFolder are,
   say hello to TarArchive, TarredFile, TarredFolder, GZipArchive and GZippedFile.
&lt;/p&gt;
&lt;p&gt;
   And when I say "easy to teach", what it really means is "find yourself a zipping example,
   and replace class name occurances of Zip{something} with Tar{somethong} or GZip{something}".
&lt;/p&gt;
&lt;p&gt;
   Sure, there are some gotchas, like the fact that a GZIP&amp;nbsp;archive cannot contain
   filenames with subfolders, are not well-suited to contain more than one compressed
   file, and can contain files without filenames. But these are details you'll get used
   to quite easily.
&lt;/p&gt;
&lt;p&gt;
   There are two things that make me really proud in that product. One is under the hood,
   and the other is a sample. First, the engine: My colleague Jacques and I have come
   up with what we call the "Storage Engine". It's an abstraction of what an archiving
   library needs in term of temp storage, in-place archive updating, and transactional
   operations on an archive. Both the new TAR and GZIP implementations use it. In short,
   it abstracts the fact that we want to always update an archive in-place when possible,
   but revert to temp files and make sure to commit those temp files with any existing
   archive upon the last modification of it. If things go well, the ZIP implementation
   will benefit from it sooner than later.
&lt;/p&gt;
&lt;p&gt;
   Second, the sample: The FTP Sample Explorer is gone, replaced with the FileSystem
   Snippet Explorer, a sample that let's you see, modify and run code snippets that show
   you the various tasks one might wish to implement. It goes straight to the point.
   No bells and whistle, no gravy, just the meat. The code is embedded in the executable
   as compressed serialized XML data. The main information (each topic's description
   and code) is nothing else than rich text. The nice thing about&amp;nbsp;this sample&amp;nbsp;is
   that in order for me to modify and add new topics, I simply need to compile the project
   with an extra define, and I'm now running the application in "admin" mode, enabling
   me to update the compressed XML file directly, for the next compilation to benefit
   from this update.
&lt;/p&gt;
&lt;p&gt;
   Though I've finished work on this 3.0 version, I already have both hands in the two
   next releases of Xceed Zip for .NET and Xceed FTP for .NET. The first one will add
   support for AES encryption, and the second one will now offer proxy support.
&lt;/p&gt;
&lt;p&gt;
   I didn't have much time to write because all those releases have a tight schedule
   I can't bust. I'm leaving Xceed in two months. Yup, I've decided it was time for me
   to move on. Until then, I have agreed to complete AES implementation, help Jacques
   kick-start proxy support and train about everybody here, each earning one of the numerous
   hats I'm wearing. It was a very difficult decision, since I have only friends at Xceed.
   Though the nine years or so I've spent here were exciting and challenging, I feel
   it's time for me to try new stuff... by myself. This isn't a divorce. I won't be far
   from Xceed, and still available to help them from time to time. As for you, dear customers
   and readers, rest assured you will stay in good hands. The team behind Xceed Zip and
   Xceed FTP, both .NET and ActiveX, will remain strong, even get stronger than it is
   now.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=b637efea-3f3b-4ed3-84b9-99a588912b33" /&gt;</description>
      <category>.NET;FTP;General;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=efb9c15a-a6e0-492b-af25-193e9be22594</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,efb9c15a-a6e0-492b-af25-193e9be22594.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Ever since I've been working with the .NET framework, most of my time was spent on
      the <a href="http://msdn2.microsoft.com/en-us/library/29kt2zfk(en-us,VS.80).aspx">System.IO</a> namespace.
      I'm not a UI guy, I'm an IO guy! The most important class in that namespace is <a href="http://msdn2.microsoft.com/en-us/library/system.io.stream.aspx">System.IO.Stream</a>.
      And since it was well-designed, probably inspired by other successful stream implementations
      (Delphi comes to mind), it's very easy to expose features using streams.
   </p>
        <p>
      My favorite use of streams is for pass-through streams. A pass-through stream
      is a class which derives from System.IO.Stream, but reads from or writes to an inner
      stream received at creation. It serves as a data modifyer or data analyser. When reading
      from a pass-through stream, it first reads from its inner stream, then processes the
      data read (potentially modifying it) and returns this data. When writing to a pass-through
      stream, it first processes the provided data (again potentially modifying it), then
      writes it to its inner stream.
   </p>
        <p>
      Xceed Zip for .NET and Xceed FTP for .NET both use a pletoria of pass-through streams.
      The most popular is <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.html">Xceed.Compression.CompressedStream</a>,
      the stream responsible for compressing data before writing it to its inner stream,
      or decompressing data read from its inner stream. But most others are internal. We've
      been juggling with the idea of exposing them for a long time, but beleive it would
      only confuse developers to "see" those new namespaces and classes. Another useful
      thing with internal classes is that we can change their interface without causing
      breaking changes.
   </p>
        <h5>TransientStream
   </h5>
        <p>
      It was a long debate before we decided to go forth with the "transient" keyword. Not
      only is it used in the TransientStream type name, but also as a property on many of
      our pass-through streams. What we meant by "transient" is "volatile", or if you prefer
      more explicit keywords, "does-not-close-its-inner-stream-when-closed". A TransientStream
      is about the simplest expression of a pass-through stream. All required property and
      method overrides simply call the inner stream. The only exception is for the Close
      method, which simply makes sure not to call Close on the inner stream. This is very
      useful when you need to pass your stream to another routine which closes the stream,
      while you don't want your stream to get closed.
   </p>
        <h5>ChecksumStream
   </h5>
        <p>
      This stream does not modify the data read from or written to, but takes the opportunity
      to calculate either a CRC32 or an Adler32 on that data. When reading, it can also
      make sure, upon closing it, that the calculated checksum matches an expected stream, else
      throw an exception. In this way, we can insert checksum calculation anywhere in a
      process without interfering nor requiring code changes.
   </p>
        <h5>CombinedStream
   </h5>
        <p>
      The deflate compression algorithm has the ability to detect the end of the data when
      decompressing. The CompressedStream is itself a pass-through stream. When reading
      from it, it first reads from the inner stream, then decompresses the data. When
      it reaches the end of the compressed data, the CompressedStream has the ability to
      return a stream on the remaining data, in case this inner stream contains more data
      after the compressed block. Why isn't this equivalent to the inner stream you might
      ask? Let's say the inner stream isn't seekable. The CompressedStream's Read method
      first reads N bytes from the inner stream, but may have found that the end of the
      compressed data is after M bytes (M &lt; N). The inner stream is already N-M bytes
      too far. The CombinedStream receives both a byte array (the unused N-M bytes) and
      the inner stream as ctor parameters, and will expose those as one contiguous stream.
      Pretty slick!
   </p>
        <h5>HeaderFooterStream
   </h5>
        <p>
      Xceed Streaming Compression for .NET exposes stream-based (as opposed to archive-based)
      compression formats. Those formats all have one thing in common: they have a header
      and a footer. Not all of them can depend on the deflate algorithm to automatically
      detect the end of the stream. That's why they need to make sure to never return the
      first M bytes and last N bytes from the inner stream, where M is the expected header
      size and N the expected footer size.
   </p>
        <h5>WindowStream
   </h5>
        <p>
      When exposing part of a zip file as a single AbstractFile, we need to make sure we
      do not read past the boundaries of that file's data in the zip file. The WindowStream
      exposes a region of its inner stream as a zero-position, N-length stream.
   </p>
        <h5>ZCryptStream
   </h5>
        <p>
      This pass-though stream automatically encrypts or decrypts the data written or read,
      using the basic Zip encryption (which is as weak as me in front of a cheese cake).
      I will be working on AES encryption very soon, and it will most probably be implemented
      as a pass-through stream too!
   </p>
        <h5>NotifyStream
   </h5>
        <p>
      Though pass-through streams can do much of the task, it is often better for the clarity
      of the code to have processing done by other classes not deriving from System.IO.Stream.
      The NotifyStream class exposes three events: ReadingFromStream, WritingToStream and
      ClosingStream. Any other class can advise for those events to intervene in the reading
      or writing process. This old class exists since the beginning of Xceed Zip for .NET,
      but it has proven very useful in the current development we are doing for Tar and
      GZip support within Xceed Zip for .NET.
   </p>
        <h5>ForwardSeekableStream
   </h5>
        <p>
      This new class created for Xceed Zip for .NET 3.0 (Tar and GZip support) can expose
      a non-seekable stream as a seekable stream when reading, or at least a stream reporting
      a Position when writing. When reading, you can call Seek with an offset behond
      the current position, and it will simply read from the non-seekable inner stream until
      well positioned. And for both reading and writing operations, it counts the number
      of bytes read or written so it can report a position (granting we knew
      the original position when created).
   </p>
        <h5>FtpAsciiDataStream
   </h5>
        <p>
      Xceed FTP for .NET also uses pass-through streams. For example, the FtpAsciiDataStream
      wraps the NetworkStream to perform convertion of LF to CR/LF on the fly when sending
      a file in ASCII mode.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=efb9c15a-a6e0-492b-af25-193e9be22594" />
      </body>
      <title>Pass-through streams</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,efb9c15a-a6e0-492b-af25-193e9be22594.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,efb9c15a-a6e0-492b-af25-193e9be22594.aspx</link>
      <pubDate>Tue, 31 Jan 2006 14:47:29 GMT</pubDate>
      <description>&lt;p&gt;
   Ever since I've been working with the .NET framework, most of my time was spent on
   the &lt;a href="http://msdn2.microsoft.com/en-us/library/29kt2zfk(en-us,VS.80).aspx"&gt;System.IO&lt;/a&gt; namespace.
   I'm not a UI guy, I'm an IO guy! The most important class in that namespace is &lt;a href="http://msdn2.microsoft.com/en-us/library/system.io.stream.aspx"&gt;System.IO.Stream&lt;/a&gt;.
   And since it was well-designed, probably inspired by other successful stream implementations
   (Delphi comes to mind), it's very easy to expose features using streams.
&lt;/p&gt;
&lt;p&gt;
   My favorite use&amp;nbsp;of streams is for pass-through streams. A pass-through stream
   is a class which derives from System.IO.Stream, but reads from or writes to an inner
   stream received at creation. It serves as a data modifyer or data analyser. When reading
   from a pass-through stream, it first reads from its inner stream, then processes the
   data read (potentially modifying it) and returns this data. When writing to a pass-through
   stream, it first processes the provided data (again potentially modifying it), then
   writes it to its inner stream.
&lt;/p&gt;
&lt;p&gt;
   Xceed Zip for .NET and Xceed FTP for .NET both use a pletoria of pass-through streams.
   The most popular is &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.html"&gt;Xceed.Compression.CompressedStream&lt;/a&gt;,
   the stream responsible for compressing data before writing it to its inner stream,
   or decompressing data read from its inner stream. But most others are internal. We've
   been juggling with the idea of exposing them for a long time, but beleive it would
   only confuse developers to "see" those new namespaces and classes. Another useful
   thing with internal classes is that we can change their interface without causing
   breaking changes.
&lt;/p&gt;
&lt;h5&gt;TransientStream
&lt;/h5&gt;
&lt;p&gt;
   It was a long debate before we decided to go forth with the "transient" keyword. Not
   only is it used in the TransientStream type name, but also as a property on many of
   our pass-through streams. What we meant by "transient" is "volatile", or if you prefer
   more explicit keywords, "does-not-close-its-inner-stream-when-closed". A TransientStream
   is about the simplest expression of a pass-through stream. All required property and
   method overrides simply call the inner stream. The only exception is for the Close
   method, which simply makes sure not to call Close on the inner stream. This is very
   useful when you need to pass your stream to another routine which closes the stream,
   while you don't want your stream to get closed.
&lt;/p&gt;
&lt;h5&gt;ChecksumStream
&lt;/h5&gt;
&lt;p&gt;
   This stream does not modify the data read from or written to, but takes the opportunity
   to calculate either a CRC32 or an Adler32 on that data. When reading, it can also
   make sure, upon closing it, that the calculated checksum matches an expected stream,&amp;nbsp;else
   throw an exception. In this way, we can insert checksum calculation anywhere in a
   process without interfering nor requiring code changes.
&lt;/p&gt;
&lt;h5&gt;CombinedStream
&lt;/h5&gt;
&lt;p&gt;
   The deflate compression algorithm has the ability to detect the end of the data when
   decompressing. The CompressedStream is itself a pass-through stream. When reading
   from it, it first reads&amp;nbsp;from the inner stream, then decompresses the data. When
   it reaches the end of the compressed data, the CompressedStream has the ability to
   return a stream on the remaining data, in case this inner stream contains more data
   after the compressed block. Why isn't this equivalent to the inner stream you might
   ask? Let's say the inner stream isn't seekable. The CompressedStream's Read method
   first reads N bytes from the inner stream, but may have found that the end of the
   compressed data is after M bytes (M &amp;lt; N). The inner stream is already N-M bytes
   too far. The CombinedStream receives both a byte array (the&amp;nbsp;unused N-M bytes)&amp;nbsp;and
   the inner stream as ctor parameters, and will expose those as one contiguous stream.
   Pretty slick!
&lt;/p&gt;
&lt;h5&gt;HeaderFooterStream
&lt;/h5&gt;
&lt;p&gt;
   Xceed Streaming Compression for .NET exposes stream-based (as opposed to archive-based)
   compression formats. Those formats all have one thing in common: they have a header
   and a footer. Not all of them can depend on the deflate algorithm to automatically
   detect the end of the stream. That's why they need to make sure to never return the
   first M bytes and last N bytes from the inner stream, where M is the expected header
   size and N the expected footer size.
&lt;/p&gt;
&lt;h5&gt;WindowStream
&lt;/h5&gt;
&lt;p&gt;
   When exposing part of a zip file as a single AbstractFile, we need to make sure we
   do not read past the boundaries of that file's data in the zip file. The WindowStream
   exposes a region of its inner stream as a zero-position, N-length stream.
&lt;/p&gt;
&lt;h5&gt;ZCryptStream
&lt;/h5&gt;
&lt;p&gt;
   This pass-though stream automatically encrypts or decrypts the data written or read,
   using the basic Zip encryption (which is as weak as me in front of a cheese cake).
   I will be working on AES encryption very soon, and it will most probably be implemented
   as a pass-through stream too!
&lt;/p&gt;
&lt;h5&gt;NotifyStream
&lt;/h5&gt;
&lt;p&gt;
   Though pass-through streams can do much of the task, it is often better for the clarity
   of the code to have processing done by other classes not deriving from System.IO.Stream.
   The NotifyStream class exposes three events: ReadingFromStream, WritingToStream and
   ClosingStream. Any other class can advise for those events to intervene in the reading
   or writing process. This old class exists since the beginning of Xceed Zip for .NET,
   but it has proven very useful in the current development we are doing for Tar and
   GZip support within Xceed Zip for .NET.
&lt;/p&gt;
&lt;h5&gt;ForwardSeekableStream
&lt;/h5&gt;
&lt;p&gt;
   This new class created for Xceed Zip for .NET 3.0 (Tar and GZip support) can expose
   a non-seekable stream as a seekable stream when reading, or at least a stream reporting
   a Position when writing. When reading, you can call Seek with an offset&amp;nbsp;behond
   the current position, and it will simply read from the non-seekable inner stream until
   well positioned. And for both reading and writing operations, it counts the number
   of bytes read or written&amp;nbsp;so it can report&amp;nbsp;a position (granting&amp;nbsp;we knew
   the original position when created).
&lt;/p&gt;
&lt;h5&gt;FtpAsciiDataStream
&lt;/h5&gt;
&lt;p&gt;
   Xceed FTP for .NET also uses pass-through streams. For example, the FtpAsciiDataStream
   wraps the NetworkStream to perform convertion of LF to CR/LF on the fly when sending
   a file in ASCII mode.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=efb9c15a-a6e0-492b-af25-193e9be22594" /&gt;</description>
      <category>.NET;Compression;FileSystem;FTP;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=c29297be-30dd-42bc-a93e-2abeb12736aa</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,c29297be-30dd-42bc-a93e-2abeb12736aa.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      One of the less known features of the Xceed FileSystem is its <a href="http://doc.xceedsoft.com/products/zipNet/doc/sources/using_filters.htm">file
      filtering capabilities</a>. Not only does it come with built-in support for filtering
      files based on name, size, attributes and dates, it also lets you easily combine criterias.
      Furthermore, as for all Xceed components, it's fully extensible.
   </p>
        <p>
      For example, let's say I want to copy files matching the <em>"*.txt"</em> filter that
      have the <em>archive</em> attribute on. The following code can be used:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, "*.txt", FileAttributes.Archive );</pre>
        <p>
      What is happening beneath the surface? The fouth parameter is <em>"params object[]
      filters"</em>. This means you can provide any number of any types of parameters. Any
      types? Not exactly. What you should see is <em>"params Filter[] filters"</em>. The <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.filtermembers.html">Filter</a> class
      is the base class for any type of filter you could think of. The Xceed FileSystem
      comes with seven built-in filter classes, divided in two categories:
   </p>
        <p>
      Operators: <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.andfiltermembers.html">AndFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.orfiltermembers.html">OrFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.notfiltermembers.html">NotFilter</a>.<br />
      Filters: <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.namefiltermembers.html">NameFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.attributefiltermembers.html">AttributeFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.sizefiltermembers.html">SizeFilter</a>, <a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.datetimefiltermembers.html">DateTimeFilter</a>.
   </p>
        <p>
      So the line of code above can be seen as this:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true,<br />
       new AndFilter( new NameFilter( "*.txt" ), new AttributeFilter(
   FileAttributes.Archive ) ) );</pre>
        <p>
      But we've decided that forcing the creation of a new <em>NameFilter</em> everytime
      you want to filter on a mask was overkill for such a common operation. That's why
      we also accept two other types of parameters. Strings are automatically converted
      to a <em>NameFilter</em>, and <em>FileAttributes</em> are automatically converted
      to an <em>AttributeFilter</em>. Finally, providing two or more filters as separate
      parameters automatically puts them in an <em>AndFilter</em>.
   </p>
        <p>
      But then, what happens to another common scenario: filtering files based on two name
      filters? Passing <em>"*.txt"</em> as the fourth parameter, and <em>"*.doc"</em> as
      the fifth would generate an <em>AndFilter</em> around them, thus only matching files
      that match the <em>".txt"</em> <strong>and</strong> the <em>".doc"</em> extensions...
      Oups!
   </p>
        <p>
      We support yet another exception: any string filter can contain a pipe character (|)
      for providing multiple name filters that will be grouped in an <em>OrFilter</em>,
      like this:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, "*.txt|*.doc" );</pre>
        <p>
      This will automatically be translated to:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, 
   <br />
       new OrFilter( new NameFilter( "*.txt" ), new NameFilter( "*.doc"
   ) ) );</pre>
        <p>
      By the way, most operator-like filters' constructors will accept strings and <em>FileAttributes</em> too,
      doing the translation to <em>NameFilter</em> and <em>AttributeFilter</em> instances for
      you.
   </p>
        <p>
      The final "hidden" feature relates to case sensitivity. By default, the FileSystem
      is case insensitive, as is the Windows platform. But since archives like zip files
      may come from other planets like Linux or Mac OS X, we wanted to support case-sensitive
      file matching. If you prepend your string with the "greater than" character (&lt;),
      the resulting <em>NameFilter</em> will be case-sensitive. The following code will
      only match files which have their extension in upper-case:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, "&gt;*.TXT" );</pre>
        <p>
      Since Windows does remember the casing of filenames, this can be very useful even
      on the Windows platform. Furthermore, since we released the library, the <a href="http://mono-project.com/Main_Page">Mono
      project</a> came to life, and our library can now be used on other platforms.
   </p>
        <h4>Extending filters
   </h4>
        <p>
      You can easily create custom filters by deriving from the <em>Xceed.FileSystem.Filter</em> class
      and overriding the <em>IsItemMatching</em> method. A <em>SearchFilter</em> class,
      which searches for a particular text within files could look like this:
   </p>
        <pre>  class SearchFilter : Filter<br />
     {<br />
       public SearchFilter( string text )<br />
         : base( FilterScope.File )<br />
       {<br />
         if( text == null )<br />
           throw new ArgumentNullException( "text"
   );<br /><br />
         if( text.Length == 0 )<br />
           throw new ArgumentException( "The text
   cannot be empty.", "text" );<br /><br />
         m_text = text;<br />
       }<br /><br />
       public override bool IsItemMatching( FileSystemItem item )<br />
       {<br />
         AbstractFile file = item as AbstractFile;<br /><br />
         if( file == null )<br />
           return false;<br /><br />
         try<br />
         {<br />
           int bufferSize = ( file.Size &lt; 0x1000000
   )<br />
             ? unchecked( ( int )file.Size
   ) 
   <br />
             : 0x1000000;<br /><br />
           byte[] search = System.Text.Encoding.Default.GetBytes(
   m_text );<br /><br />
           if( search.Length &lt;= bufferSize )<br />
           {<br />
             byte[] buffer = new byte[ bufferSize
   ];<br />
             int found = 0;<br /><br />
             using( BinaryReader reader
   = new BinaryReader( file.OpenRead( FileShare.ReadWrite ) ) )<br />
             {<br />
               int read = 0;<br /><br />
               while( ( read =
   reader.Read( buffer, 0, bufferSize ) ) &gt; 0 )<br />
               {<br />
                 found
   = FindBuffer( buffer, 0, read, search, found );<br /><br />
                 if(
   found == search.Length )<br />
                  
   return true;<br />
               }<br />
             }<br />
           }      
   <br />
         }<br />
         catch {}<br /><br />
         return false;<br />
       }<br /><br />
       private int FindBuffer( 
   <br />
         byte[] source, 
   <br />
         int sourceStart, 
   <br />
         int sourceCount, 
   <br />
         byte[] search, 
   <br />
         int searchIndex )<br />
       {<br />
         // TODO: Param check!<br /><br />
         for( int i=0; i&lt;sourceCount; i++ )<br />
         {<br />
           if( source[ sourceStart + i ] == search[
   searchIndex ] )<br />
           {<br />
             if( ++searchIndex == search.Length
   )<br />
               return searchIndex;<br />
           }<br />
           else<br />
           {<br />
             searchIndex = 0;<br />
           }<br />
         }<br /><br />
         return searchIndex;<br />
       }<br /><br />
       private string m_text; // = null<br />
     }</pre>
        <p>
      Using this custom filter, you can now copy only files that contain a particular text:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, new SearchFilter( "allo" ) );</pre>
        <h4>Conditionally recursing
   </h4>
        <p>
      One missing feature we had with the filtering will be addressed with today's release.
      There were no way to control which subfolders to recurse into or not when calling
      methods accepting filters (<em>CopyFilesTo</em>, <em>MoveFilesTo</em>, <em>GetFiles</em>, <em>GetFolders</em>).
      The <em>FilterScope.Folder</em> value wasn't preventing recursing into subfolders.
      It was only meant to include or exclude folder entries from being copied. But passing
      "true" or "false" as the "recurse" parameter was an all or nothing deal.
   </p>
        <p>
      Today, we introduce a new scope: <em>FilterScope.Recurse</em>. It does not interfere
      with the <em>File</em> or <em>Folder</em> socpe, and only determines if we should
      continue matching files into each subfolder. Its number one use is for excluding subfolders:
   </p>
        <pre>  sourceFolder.CopyFilesTo( destFolder, true, true, 
   <br />
       "*.txt", new NotFilter( new NameFilter( "Bar", FilterScope.Recurse
   ) ) );</pre>
        <p>
      The way you combine <em>"Recurse"</em> filters and other filters is irrelevant. When
      deciding to copy files or folders, the library ignores any filters with the <em>Recurse</em> scope.
      When deciding to call itself recursively, the library ignores any filters with the <em>File</em> or <em>Folder</em> scope.
   </p>
        <p>
      We plan on providing new types of filters. Suggestions welcomed!
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=c29297be-30dd-42bc-a93e-2abeb12736aa" />
      </body>
      <title>Filtering files with the Xceed FileSystem</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,c29297be-30dd-42bc-a93e-2abeb12736aa.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,c29297be-30dd-42bc-a93e-2abeb12736aa.aspx</link>
      <pubDate>Tue, 17 Jan 2006 14:35:07 GMT</pubDate>
      <description>&lt;p&gt;
   One of the less known features of the Xceed FileSystem is its &lt;a href="http://doc.xceedsoft.com/products/zipNet/doc/sources/using_filters.htm"&gt;file
   filtering capabilities&lt;/a&gt;. Not only does it come with built-in support for filtering
   files based on name, size, attributes and dates, it also lets you easily combine criterias.
   Furthermore, as for all Xceed components, it's fully extensible.
&lt;/p&gt;
&lt;p&gt;
   For example, let's say I want to copy files matching the &lt;em&gt;"*.txt"&lt;/em&gt; filter that
   have the &lt;em&gt;archive&lt;/em&gt; attribute on. The following code can be used:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true, "*.txt", FileAttributes.Archive );&lt;/pre&gt;
&lt;p&gt;
   What is happening beneath the surface? The fouth parameter is&amp;nbsp;&lt;em&gt;"params object[]
   filters"&lt;/em&gt;. This means you can provide any number of any types of parameters. Any
   types? Not exactly. What you should see is &lt;em&gt;"params Filter[] filters"&lt;/em&gt;. The &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.filtermembers.html"&gt;Filter&lt;/a&gt; class
   is the base class for any type of filter you could think of. The Xceed FileSystem
   comes with seven built-in filter classes, divided in two categories:
&lt;/p&gt;
&lt;p&gt;
   Operators: &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.andfiltermembers.html"&gt;AndFilter&lt;/a&gt;, &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.orfiltermembers.html"&gt;OrFilter&lt;/a&gt;, &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.notfiltermembers.html"&gt;NotFilter&lt;/a&gt;.&lt;br&gt;
   Filters: &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.namefiltermembers.html"&gt;NameFilter&lt;/a&gt;, &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.attributefiltermembers.html"&gt;AttributeFilter&lt;/a&gt;, &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.sizefiltermembers.html"&gt;SizeFilter&lt;/a&gt;, &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/index.htm?page=xceed.filesystem.datetimefiltermembers.html"&gt;DateTimeFilter&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
   So the line of code above can be seen as this:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true,&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new AndFilter( new NameFilter( "*.txt" ), new AttributeFilter(
FileAttributes.Archive ) ) );&lt;/pre&gt;
&lt;p&gt;
   But we've decided that forcing the creation of a new &lt;em&gt;NameFilter&lt;/em&gt; everytime
   you want to filter on a mask was overkill for such a common operation. That's why
   we also accept two other types of parameters. Strings are automatically converted
   to a &lt;em&gt;NameFilter&lt;/em&gt;, and &lt;em&gt;FileAttributes&lt;/em&gt; are automatically converted
   to an &lt;em&gt;AttributeFilter&lt;/em&gt;. Finally, providing two or more filters as separate
   parameters automatically puts them in an &lt;em&gt;AndFilter&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
   But then, what happens to another common scenario: filtering files based on two name
   filters? Passing &lt;em&gt;"*.txt"&lt;/em&gt; as the fourth parameter, and &lt;em&gt;"*.doc"&lt;/em&gt; as
   the fifth would generate an &lt;em&gt;AndFilter&lt;/em&gt; around them, thus only matching files
   that match the &lt;em&gt;".txt"&lt;/em&gt;&amp;nbsp;&lt;strong&gt;and&lt;/strong&gt; the &lt;em&gt;".doc"&lt;/em&gt; extensions...
   Oups!
&lt;/p&gt;
&lt;p&gt;
   We support yet another exception: any string filter can contain a pipe character (|)
   for providing multiple name filters that will be grouped in an &lt;em&gt;OrFilter&lt;/em&gt;,
   like this:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true, "*.txt|*.doc" );&lt;/pre&gt;
&lt;p&gt;
   This will automatically be translated to:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; new OrFilter( new NameFilter( "*.txt" ), new NameFilter( "*.doc"
) ) );&lt;/pre&gt;
&lt;p&gt;
   By the way, most operator-like filters' constructors will accept strings and &lt;em&gt;FileAttributes&lt;/em&gt; too,
   doing the translation to &lt;em&gt;NameFilter&lt;/em&gt; and &lt;em&gt;AttributeFilter&lt;/em&gt; instances&amp;nbsp;for
   you.
&lt;/p&gt;
&lt;p&gt;
   The final "hidden" feature relates to case sensitivity. By default, the FileSystem
   is case insensitive, as is the Windows platform. But since archives like zip files
   may come from other planets like Linux or Mac OS X, we wanted to support case-sensitive
   file matching. If you prepend your string with the "greater than" character (&amp;lt;),
   the resulting &lt;em&gt;NameFilter&lt;/em&gt; will be case-sensitive. The following code will
   only match files which have their extension in upper-case:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true, "&amp;gt;*.TXT" );&lt;/pre&gt;
&lt;p&gt;
   Since Windows does remember the casing of filenames, this can be very useful even
   on the Windows platform. Furthermore, since we released the library, the &lt;a href="http://mono-project.com/Main_Page"&gt;Mono
   project&lt;/a&gt; came to life, and our library can now be used on other platforms.
&lt;/p&gt;
&lt;h4&gt;Extending filters
&lt;/h4&gt;
&lt;p&gt;
   You can easily create custom filters by deriving from the &lt;em&gt;Xceed.FileSystem.Filter&lt;/em&gt; class
   and overriding the &lt;em&gt;IsItemMatching&lt;/em&gt; method. A &lt;em&gt;SearchFilter&lt;/em&gt; class,
   which searches for a particular text within files could look like this:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp; class SearchFilter : Filter&lt;br&gt;
&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public SearchFilter( string text )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : base( FilterScope.File )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if( text == null )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentNullException( "text"
);&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if( text.Length == 0 )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException( "The text
cannot be empty.", "text" );&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; m_text = text;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; public override bool IsItemMatching( FileSystemItem item )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; AbstractFile file = item as AbstractFile;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if( file == null )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int bufferSize = ( file.Size &amp;lt; 0x1000000
)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ? unchecked( ( int )file.Size
) 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : 0x1000000;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] search = System.Text.Encoding.Default.GetBytes(
m_text );&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if( search.Length &amp;lt;= bufferSize )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] buffer = new byte[ bufferSize
];&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int found = 0;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; using( BinaryReader reader
= new BinaryReader( file.OpenRead( FileShare.ReadWrite ) ) )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int read = 0;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; while( ( read =
reader.Read( buffer, 0, bufferSize ) ) &amp;gt; 0 )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; found
= FindBuffer( buffer, 0, read, search, found );&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if(
found == search.Length )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
return true;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; catch {}&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return false;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private int FindBuffer( 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] source, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int sourceStart, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int sourceCount, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; byte[] search, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; int searchIndex )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // TODO: Param check!&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; for( int i=0; i&amp;lt;sourceCount; i++ )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if( source[ sourceStart + i ] == search[
searchIndex ] )&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if( ++searchIndex == search.Length
)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return searchIndex;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; searchIndex = 0;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return searchIndex;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; private string m_text; // = null&lt;br&gt;
&amp;nbsp; }&lt;/pre&gt;
&lt;p&gt;
   Using this custom filter, you can now copy only files that contain a particular text:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true, new SearchFilter( "allo" ) );&lt;/pre&gt;
&lt;h4&gt;Conditionally recursing
&lt;/h4&gt;
&lt;p&gt;
   One missing feature we had with the filtering will be addressed with today's release.
   There were no way to control which subfolders to recurse into&amp;nbsp;or not when calling
   methods accepting filters (&lt;em&gt;CopyFilesTo&lt;/em&gt;, &lt;em&gt;MoveFilesTo&lt;/em&gt;, &lt;em&gt;GetFiles&lt;/em&gt;, &lt;em&gt;GetFolders&lt;/em&gt;).
   The &lt;em&gt;FilterScope.Folder&lt;/em&gt; value wasn't preventing recursing into subfolders.
   It was only meant to include or exclude folder entries from being copied. But passing
   "true" or "false"&amp;nbsp;as the "recurse" parameter was an all or nothing deal.
&lt;/p&gt;
&lt;p&gt;
   Today, we introduce a new scope: &lt;em&gt;FilterScope.Recurse&lt;/em&gt;. It does not interfere
   with the &lt;em&gt;File&lt;/em&gt; or &lt;em&gt;Folder&lt;/em&gt; socpe, and only determines if we should
   continue matching files into each subfolder. Its number one use is for excluding subfolders:
&lt;/p&gt;
&lt;pre&gt;&amp;nbsp;&amp;nbsp;sourceFolder.CopyFilesTo( destFolder, true, true, 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; "*.txt", new NotFilter( new NameFilter( "Bar", FilterScope.Recurse
) ) );&lt;/pre&gt;
&lt;p&gt;
   The way you combine &lt;em&gt;"Recurse"&lt;/em&gt; filters and other filters is irrelevant. When
   deciding to copy files or folders, the library ignores any filters with the &lt;em&gt;Recurse&lt;/em&gt; scope.
   When deciding to call itself recursively, the library ignores any filters with the &lt;em&gt;File&lt;/em&gt; or &lt;em&gt;Folder&lt;/em&gt; scope.
&lt;/p&gt;
&lt;p&gt;
   We plan on providing new types of filters. Suggestions welcomed!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=c29297be-30dd-42bc-a93e-2abeb12736aa" /&gt;</description>
      <category>.NET;FileSystem</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=928711f3-f289-4809-92ba-1d3d42e24111</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,928711f3-f289-4809-92ba-1d3d42e24111.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I must admit, I'm no database wizz. It's been a looooong time since I've played with
      SQL, and I never really digged into System.Data. The rare moments I required a data
      connection, the design-time experience was enough, oh, and that Fill call on that
      adapter! q;-)
   </p>
        <p>
      Recently, a customer explained he was using an SqlDataReader to fetch its data on
      demand, to avoid loading too much. One of the fields was a byte array containing a
      GZip file. He was using the static method <a href="http://doc.xceedsoft.com/products/streamNet/ref/xceed.compression.formats.gzipcompressedstream.decompress.html">GZipCompressedStream.Decompress</a> to
      get the data in that GZip file. Unfortunately, the data was sometimes quite large,
      and this technique prevented him from using <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDataSqlClientSqlDataReaderClassGetBytesTopic.asp">SqlDataReader.GetBytes</a> (exposed
      in the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdataidatarecordclasstopic.asp">IDataRecord</a> interface),
      which allows to read only chunks of a field at a time.
   </p>
        <p>
      Bummer... My "Streams everywhere" modo was challenged. You see, <a href="http://www.xceedsoft.com/redirect/stream_net/">Xceed
      Streaming Compression for .NET</a> allows you to either decompress a single byte array
      in one operation (stateless), or wrap a <a href="http://doc.xceedsoft.com/products/streamNet/ref/xceed.compression.formats.gzipcompressedstream.html">GZipCompressedStream</a> around
      your source stream and read from it to decompress data on the fly. But in this case,
      no streams. Nada. Or if there is one, I didn't find it.
   </p>
        <p>
      I was not going to get defeated by that mere absence. The "Streaming" in "Xceed Streaming
      Compression for .NET" is exactly about that scenario. It turns out it was quite easy
      to overcome this little problem. I created myself a DataRecordStream class, which
      derives from System.IO.Stream.
   </p>
        <p>
      Apart from the usual overrides required when deriving from System.IO.Stream, I expose
      a constructor requiring an IDataRecord parameter and the index of the field to expose
      as a stream.
   </p>
        <p>
        </p>
        <pre>    public DataRecordStream( IDataRecord record, int fieldIndex )<br />
   {<br />
   if( record == null )<br />
   throw new ArgumentNullException( "record" );<br /><br />
   if( ( fieldIndex &lt; 0 ) || ( fieldIndex &gt;= record.FieldCount ) )<br />
   throw new ArgumentOutOfRangeException( "fieldIndex", fieldIndex, "Invalid field index."
   );<br /><br />
   m_record = record;<br />
   m_field = fieldIndex;<br />
   }<br /></pre>
        <p>
        </p>
        <p>
      Then, when Read is called, I simply turn to my IDataRecord's GetBytes method to fill
      that buffer.
   </p>
        <p>
        </p>
        <pre>    public override int Read( byte[] buffer, int offset, int count )<br />
   {<br />
   long read = m_record.GetBytes( m_field, m_position, buffer, offset, count );<br /><br />
   m_position += read;<br /><br />
   if( ( m_length != -1 ) &amp;&amp; ( m_position &gt; m_length ) )<br />
   {<br />
   // The reported length was smaller than the actual size.<br />
   // We update the length dynamically.<br />
   m_length = m_position;<br />
   }<br /><br />
   return unchecked( ( int )read );<br />
   }<br /></pre>
        <p>
        </p>
        <p>
      The rest is just glue for managing the position and allowing seeking. The good part
      about this new class is that you can now wrap any pass-thru stream around it, for
      example a GZipCompressedStream. My customer can now read text compressed in a GZip
      file stored in one of its database fields quite easily, without consuming too much
      memory.
   </p>
        <p>
        </p>
        <pre>      SqlConnection connection = new SqlConnection( 
   <br />
   "integrated security=SSPI;data source=xxx;initial catalog=GZipTest" );<br /><br />
   connection.Open();<br /><br />
   try<br />
   {<br />
   using( SqlCommand command = new SqlCommand( "SELECT * FROM GZipTestTable", connection
   ) )<br />
   {<br />
   using( SqlDataReader dataReader = command.ExecuteReader() )<br />
   {<br />
   while( dataReader.Read() )<br />
   {<br />
   using( StreamReader textReader = new StreamReader(<br />
   new GZipCompressedStream(<br />
   new DataRecordStream( 
   <br />
   dataReader, dataReader.GetOrdinal( "GZipField" ) ) ) ) )<br />
   {<br />
   string line;<br /><br />
   while( ( line = textReader.ReadLine() ) != null )<br />
   {<br />
   Console.WriteLine( line );<br />
   }<br />
   }<br />
   }<br />
   }<br />
   }<br />
   }<br />
   finally<br />
   {<br />
   connection.Close();<br />
   }<br /></pre>
        <p>
        </p>
        <p>
      I have made a VB.NET version of the class too. Enjoy!
   </p>
        <p>
          <a href="http://blogs.xceedsoft.com/plantem/content/binary/DataRecordStream.zip">DataRecordStream.zip
      (3.34 KB)</a>
        </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=928711f3-f289-4809-92ba-1d3d42e24111" />
      </body>
      <title>Uncompressing data from a DataReader</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,928711f3-f289-4809-92ba-1d3d42e24111.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,928711f3-f289-4809-92ba-1d3d42e24111.aspx</link>
      <pubDate>Thu, 24 Nov 2005 14:25:04 GMT</pubDate>
      <description>&lt;p&gt;
   I must admit, I'm no database wizz. It's been a looooong time since I've played with
   SQL, and I never really digged into System.Data. The rare moments I required a data
   connection, the design-time experience was enough, oh, and that Fill call on that
   adapter! q;-)
&lt;/p&gt;
&lt;p&gt;
   Recently, a customer explained he was using an SqlDataReader to fetch its data on
   demand, to avoid loading too much. One of the fields was a byte array containing a
   GZip file. He was using the static method &lt;a href="http://doc.xceedsoft.com/products/streamNet/ref/xceed.compression.formats.gzipcompressedstream.decompress.html"&gt;GZipCompressedStream.Decompress&lt;/a&gt; to
   get the data in that GZip file. Unfortunately, the data was sometimes quite large,
   and this technique prevented him from using &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDataSqlClientSqlDataReaderClassGetBytesTopic.asp"&gt;SqlDataReader.GetBytes&lt;/a&gt; (exposed
   in the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdataidatarecordclasstopic.asp"&gt;IDataRecord&lt;/a&gt; interface),
   which allows to read only chunks of a field at a time.
&lt;/p&gt;
&lt;p&gt;
   Bummer... My "Streams everywhere" modo was challenged. You see, &lt;a href="http://www.xceedsoft.com/redirect/stream_net/"&gt;Xceed
   Streaming Compression for .NET&lt;/a&gt; allows you to either decompress a single byte array
   in one operation (stateless), or wrap a &lt;a href="http://doc.xceedsoft.com/products/streamNet/ref/xceed.compression.formats.gzipcompressedstream.html"&gt;GZipCompressedStream&lt;/a&gt; around
   your source stream and read from it to decompress data on the fly. But in this case,
   no streams. Nada. Or if there is one, I didn't find it.
&lt;/p&gt;
&lt;p&gt;
   I was not going to get defeated by that mere absence. The "Streaming" in "Xceed Streaming
   Compression for .NET" is exactly about that scenario. It turns out it was quite easy
   to overcome this little problem. I created myself a DataRecordStream class, which
   derives from System.IO.Stream.
&lt;/p&gt;
&lt;p&gt;
   Apart from the usual overrides required when deriving from System.IO.Stream, I expose
   a constructor requiring an IDataRecord parameter and the index of the field to expose
   as a stream.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre&gt;    public DataRecordStream( IDataRecord record, int fieldIndex )&lt;br&gt;
{&lt;br&gt;
if( record == null )&lt;br&gt;
throw new ArgumentNullException( "record" );&lt;br&gt;
&lt;br&gt;
if( ( fieldIndex &amp;lt; 0 ) || ( fieldIndex &amp;gt;= record.FieldCount ) )&lt;br&gt;
throw new ArgumentOutOfRangeException( "fieldIndex", fieldIndex, "Invalid field index."
);&lt;br&gt;
&lt;br&gt;
m_record = record;&lt;br&gt;
m_field = fieldIndex;&lt;br&gt;
}&lt;br&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
   Then, when Read is called, I simply turn to my IDataRecord's GetBytes method to fill
   that buffer.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre&gt;    public override int Read( byte[] buffer, int offset, int count )&lt;br&gt;
{&lt;br&gt;
long read = m_record.GetBytes( m_field, m_position, buffer, offset, count );&lt;br&gt;
&lt;br&gt;
m_position += read;&lt;br&gt;
&lt;br&gt;
if( ( m_length != -1 ) &amp;amp;&amp;amp; ( m_position &amp;gt; m_length ) )&lt;br&gt;
{&lt;br&gt;
// The reported length was smaller than the actual size.&lt;br&gt;
// We update the length dynamically.&lt;br&gt;
m_length = m_position;&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
return unchecked( ( int )read );&lt;br&gt;
}&lt;br&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
   The rest is just glue for managing the position and allowing seeking. The good part
   about this new class is that you can now wrap any pass-thru stream around it, for
   example a GZipCompressedStream. My customer can now read text compressed in a GZip
   file stored in one of its database fields quite easily, without consuming too much
   memory.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;pre&gt;      SqlConnection connection = new SqlConnection( 
&lt;br&gt;
"integrated security=SSPI;data source=xxx;initial catalog=GZipTest" );&lt;br&gt;
&lt;br&gt;
connection.Open();&lt;br&gt;
&lt;br&gt;
try&lt;br&gt;
{&lt;br&gt;
using( SqlCommand command = new SqlCommand( "SELECT * FROM GZipTestTable", connection
) )&lt;br&gt;
{&lt;br&gt;
using( SqlDataReader dataReader = command.ExecuteReader() )&lt;br&gt;
{&lt;br&gt;
while( dataReader.Read() )&lt;br&gt;
{&lt;br&gt;
using( StreamReader textReader = new StreamReader(&lt;br&gt;
new GZipCompressedStream(&lt;br&gt;
new DataRecordStream( 
&lt;br&gt;
dataReader, dataReader.GetOrdinal( "GZipField" ) ) ) ) )&lt;br&gt;
{&lt;br&gt;
string line;&lt;br&gt;
&lt;br&gt;
while( ( line = textReader.ReadLine() ) != null )&lt;br&gt;
{&lt;br&gt;
Console.WriteLine( line );&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
}&lt;br&gt;
finally&lt;br&gt;
{&lt;br&gt;
connection.Close();&lt;br&gt;
}&lt;br&gt;
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
   I have made a VB.NET version of the class too. Enjoy!
&lt;/p&gt;
&lt;p&gt;
   &lt;a href="http://blogs.xceedsoft.com/plantem/content/binary/DataRecordStream.zip"&gt;DataRecordStream.zip
   (3.34 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=928711f3-f289-4809-92ba-1d3d42e24111" /&gt;</description>
      <category>.NET;Compression</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=e89375a1-63e3-470f-b804-28ef40192554</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,e89375a1-63e3-470f-b804-28ef40192554.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I previously <a href="http://blogs.xceedsoft.com/plantem/default.aspx?month=2005-06#a5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3">gave
      a glimpse</a> of how to zip into an HttpResponse's OutputStream, but it wasn't explaining
      all aspects of zipping from ASP.NET. So I'll get in more details here.
   </p>
        <p>
      First, I have used my fantastic talent in UI designs to create this web page:
   </p>
        <p>
          <img src="http://blogs.xceedsoft.com/plantem/content/binary/ZipAndSend.png" border="0" />
        </p>
        <p>
      Yup, three checkboxes and a button is enough gadgets for me!
   </p>
        <p>
      The first piece of code involves Application_Start. Since I know I won't be zipping
      gazillions of bytes, I want my web page to use memory as a temporary location for
      compressed data. How you do this with Xceed Zip for .NET is simple: You create a RAM
      drive! Oh the good old days of RAM drives...
   </p>
        <p>
        </p>
        <pre>    protected void Application_Start(Object sender, EventArgs e)
    {
      Xceed.Zip.Licenser.LicenseKey = "ZIN23-#####-#####-####";
      ZipArchive.DefaultTempFolder = new MemoryFolder();
    }
</pre>
        <p>
        </p>
        <p>
      This new MemoryFolder is acting exactly like a per-process RAM drive. It's an AbstractFolder
      like any other AbstractFolder. The TempFolder of all new ZipArchive instances will be
      initialized to that value. Application_Start is also a great place where to set
      your license key, before anything else.
   </p>
        <p>
      We're now ready for the button's click event. Again, I want to avoid write access
      on the hard drive, and wish to zip directly in the response stream. But the idea behind
      the Xceed FileSystem is to copy source files and folders to destination files and
      folders. How can I zip into a Stream? The StreamFile class comes to the rescue. It
      lets you expose a Stream as if it were an AbstractFile. Then, you can pass this StreamFile
      to the ZipArchive's constructor, to tell that new instance to write into that Stream.
      The rest is glue code for my wonderful ASP.NET application to zip the correct files.
   </p>
        <p>
        </p>
        <pre>    private void Button1_Click(object sender, System.EventArgs e)
    {
      if( !CheckBox1.Checked &amp;&amp; !CheckBox2.Checked &amp;&amp; !CheckBox3.Checked )
      {
        // Redirect to error page...
        return;
      }

      // The "MACHINE\ASP_NET" user must have read access to that folder.
      DiskFolder source = new DiskFolder( @"d:\" );

      // We want the client-side to recognize the upcoming file as a zip file.
      this.Response.ContentType = "application/zip";
      this.Response.AddHeader( "Content-Disposition", "attachment; filename=YourFiles.zip" );

      // We will zip directly in the response stream. The temporary compressed
      // data will be written to the ZipArchive's TempFolder, thus the MemoryFolder 
      // we set in Application_Start.
      ZipArchive destination = new ZipArchive( new StreamFile( this.Response.OutputStream ) );

      // And finally we zip in a single operation. If we had to zip more than
      // one source, we could have used ZipArchive.BeginUpdate/EndUpdate.
      ArrayList nameFilters = new ArrayList();

      if( CheckBox1.Checked )
        nameFilters.Add( new NameFilter( "*.txt" ) );

      if( CheckBox2.Checked )
        nameFilters.Add( new NameFilter( "*.jpg" ) );

      if( CheckBox3.Checked )
        nameFilters.Add( new NameFilter( "*.exe|*.dll" ) );

      // Passing more than one filter to CopyFilesTo does an "AndFilter"
      // by default.
      Filter mainFilter = ( nameFilters.Count == 1 )
        ? nameFilters[ 0 ] as Filter
        : new OrFilter( nameFilters.ToArray( typeof( NameFilter ) ) );

      source.CopyFilesTo( destination, false, true, mainFilter );

      this.Response.End();
    }
</pre>
        <p>
      We now have an ASP.NET application which only requires read access to the source
      files and folders to zip. Everything else is done in memory, without drifting away
      from the logic of the Xceed FileSystem; manipulating files and folders.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=e89375a1-63e3-470f-b804-28ef40192554" />
      </body>
      <title>Zipping from an ASP.NET - A real sample</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,e89375a1-63e3-470f-b804-28ef40192554.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,e89375a1-63e3-470f-b804-28ef40192554.aspx</link>
      <pubDate>Fri, 11 Nov 2005 14:26:28 GMT</pubDate>
      <description>&lt;p&gt;
   I previously &lt;a href="http://blogs.xceedsoft.com/plantem/default.aspx?month=2005-06#a5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3"&gt;gave
   a glimpse&lt;/a&gt; of how to zip into an HttpResponse's OutputStream, but it wasn't explaining
   all aspects of zipping from ASP.NET. So I'll get in more details here.
&lt;/p&gt;
&lt;p&gt;
   First, I have used my&amp;nbsp;fantastic talent in UI designs to create this web page:
&lt;/p&gt;
&lt;p&gt;
   &lt;img src="http://blogs.xceedsoft.com/plantem/content/binary/ZipAndSend.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
   Yup, three checkboxes and a button is enough gadgets for me!
&lt;/p&gt;
&lt;p&gt;
   The first piece of code involves Application_Start. Since I know I won't be zipping
   gazillions of bytes, I want my web page to use memory as a temporary location for
   compressed data. How you do this with Xceed Zip for .NET is simple: You create a RAM
   drive! Oh the good old days of RAM drives...
&lt;/p&gt;
&lt;p&gt;
&lt;pre&gt;    protected void Application_Start(Object sender, EventArgs e)
    {
      Xceed.Zip.Licenser.LicenseKey = "ZIN23-#####-#####-####";
      ZipArchive.DefaultTempFolder = new MemoryFolder();
    }
&lt;/pre&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
   This new MemoryFolder is acting exactly like a per-process RAM drive. It's an AbstractFolder
   like any other AbstractFolder. The TempFolder of all new ZipArchive instances will&amp;nbsp;be
   initialized to that value.&amp;nbsp;Application_Start is also a great place where to set
   your license key, before anything else.
&lt;/p&gt;
&lt;p&gt;
   We're now ready for the button's click event. Again, I want to avoid write access
   on the hard drive, and wish to zip directly in the response stream. But the idea behind
   the Xceed FileSystem is to copy source files and folders to destination files and
   folders. How can I zip into a Stream? The StreamFile class comes to the rescue. It
   lets you expose a Stream as if it were an AbstractFile. Then, you can pass this StreamFile
   to the ZipArchive's constructor, to tell that new instance to write into that Stream.
   The rest is glue code for my wonderful ASP.NET application to zip the correct files.
&lt;/p&gt;
&lt;p&gt;
&lt;pre&gt;    private void Button1_Click(object sender, System.EventArgs e)
    {
      if( !CheckBox1.Checked &amp;amp;&amp;amp; !CheckBox2.Checked &amp;amp;&amp;amp; !CheckBox3.Checked )
      {
        // Redirect to error page...
        return;
      }

      // The "MACHINE\ASP_NET" user must have read access to that folder.
      DiskFolder source = new DiskFolder( @"d:\" );

      // We want the client-side to recognize the upcoming file as a zip file.
      this.Response.ContentType = "application/zip";
      this.Response.AddHeader( "Content-Disposition", "attachment; filename=YourFiles.zip" );

      // We will zip directly in the response stream. The temporary compressed
      // data will be written to the ZipArchive's TempFolder, thus the MemoryFolder 
      // we set in Application_Start.
      ZipArchive destination = new ZipArchive( new StreamFile( this.Response.OutputStream ) );

      // And finally we zip in a single operation. If we had to zip more than
      // one source, we could have used ZipArchive.BeginUpdate/EndUpdate.
      ArrayList nameFilters = new ArrayList();

      if( CheckBox1.Checked )
        nameFilters.Add( new NameFilter( "*.txt" ) );

      if( CheckBox2.Checked )
        nameFilters.Add( new NameFilter( "*.jpg" ) );

      if( CheckBox3.Checked )
        nameFilters.Add( new NameFilter( "*.exe|*.dll" ) );

      // Passing more than one filter to CopyFilesTo does an "AndFilter"
      // by default.
      Filter mainFilter = ( nameFilters.Count == 1 )
        ? nameFilters[ 0 ] as Filter
        : new OrFilter( nameFilters.ToArray( typeof( NameFilter ) ) );

      source.CopyFilesTo( destination, false, true, mainFilter );

      this.Response.End();
    }
&lt;/pre&gt;
&lt;p&gt;
   We&amp;nbsp;now have an ASP.NET application which only requires read access to the source
   files and folders to zip. Everything else is done in memory, without drifting away
   from the logic of the Xceed FileSystem; manipulating files and folders.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=e89375a1-63e3-470f-b804-28ef40192554" /&gt;</description>
      <category>.NET;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=af20b143-cb89-4b4e-8006-298cdff4c0ce</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,af20b143-cb89-4b4e-8006-298cdff4c0ce.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Just in case my <a href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,78f813ed-96ee-4752-8ab5-2061b0f9d758.aspx">previous
      post on the subject</a> did not ring a bell, the release of version 2.1 of Xceed FTP
      for .NET means you can directly unzip from a zip file located on an FTP server, without
      downloading the file first! Look at the following code:
   </p>
        <p>
        </p>
        <pre>  using( FtpConnection connection = new FtpConnection( "ftp.xceed.com" ) )
  {
    FtpFile source = new FtpFile( connection, @"/images/Flowers/Backup/Flowers.zip" );
    DiskFolder dest = new DiskFolder( @"d:\temp\flowers" );

    ZipArchive zip = new ZipArchive( source );
    zip.CopyFilesTo( dest, true, true );
  }
</pre>
        <p>
      The secret behind this code is the kind of stream "FtpFile.OpenRead" returns. Though
      we are dealing with a network connection, this stream is fully seekable! The FtpFile
      takes advantage of the "REST" FTP command, which tells the FTP server we wish to start
      the transfer at a specific offset. Thus, when the ZipArchive needs to seek at the
      end of the file to locate the ending header, a proper "REST" command is issued to
      avoid having to read all the zip file first. And the same happens when reading the
      central directory, or unzipping specific files.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=af20b143-cb89-4b4e-8006-298cdff4c0ce" />
      </body>
      <title>Unzipping from an FTP server</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,af20b143-cb89-4b4e-8006-298cdff4c0ce.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,af20b143-cb89-4b4e-8006-298cdff4c0ce.aspx</link>
      <pubDate>Tue, 01 Nov 2005 20:15:40 GMT</pubDate>
      <description>&lt;p&gt;
   Just in case my &lt;a href="http://blogs.xceedsoft.com/plantem/PermaLink,guid,78f813ed-96ee-4752-8ab5-2061b0f9d758.aspx"&gt;previous
   post on the subject&lt;/a&gt; did not ring a bell, the release of version 2.1 of Xceed FTP
   for .NET means you can directly unzip from a zip file located on an FTP server, without
   downloading&amp;nbsp;the file&amp;nbsp;first! Look at the following code:
&lt;/p&gt;
&lt;p&gt;
&lt;pre&gt;  using( FtpConnection connection = new FtpConnection( "ftp.xceed.com" ) )
  {
    FtpFile source = new FtpFile( connection, @"/images/Flowers/Backup/Flowers.zip" );
    DiskFolder dest = new DiskFolder( @"d:\temp\flowers" );

    ZipArchive zip = new ZipArchive( source );
    zip.CopyFilesTo( dest, true, true );
  }
&lt;/pre&gt;
&lt;p&gt;
   The secret behind this code is the kind of stream "FtpFile.OpenRead" returns. Though
   we are dealing with a network connection, this stream is fully seekable! The FtpFile
   takes advantage of the "REST" FTP command, which tells the FTP server we wish to start
   the transfer at a specific offset. Thus, when the ZipArchive needs to seek at the
   end of the file to locate the ending header, a proper "REST" command is issued to
   avoid having to read all the zip file first. And the same happens when reading the
   central directory, or unzipping specific files.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=af20b143-cb89-4b4e-8006-298cdff4c0ce" /&gt;</description>
      <category>.NET;FileSystem;FTP;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=78f813ed-96ee-4752-8ab5-2061b0f9d758</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,78f813ed-96ee-4752-8ab5-2061b0f9d758.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I'm glad to announce that Xceed FTP for .NET 2.1 is <a href="http://xceedsoft.com/download/downloadform.aspx?produitID=371">now
      available for download</a>. I've been working on this release for the past few months,
      and I'm very excited to finally see the FTP FileSystem come to life.
   </p>
        <p>
      For those not familiar with the Xceed FileSystem, which comes with Xceed Zip for .NET,
      here is some code that sheds some light on what you can do with it. Consider these
      variables of the same base type:
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      A file on disk</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      first = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFile(
      @"d:\FileSystem.txt" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      Another file on disk</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      second = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFile(
      @"c:\temp\AnotherFileSystem.txt" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      A file compressed in a zip file on disk</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      third = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> ZippedFile( </span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFile(
      @"c:\temp\data.zip" ), "FileSystemInAZip.txt" );;</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      A file in the isolated storage</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      fourth = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> IsolatedFile(
      "Isolated.txt" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      A file in memory (random name)</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      fifth = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> MemoryFile();</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      A file compressed in a zip file in memory</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      sixth = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> ZippedFile( </span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> MemoryFile(),
      "VolatileFileSystem.txt" );</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      You can copy files around very easily:
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      Copying the first file anywhere else is always the same!</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">first.CopyTo(
      second, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">first.CopyTo(
      third, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">first.CopyTo(
      fourth, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">first.CopyTo(
      fifth, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">first.CopyTo(
      sixth, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      And accessing the contents of any file is always the same:
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">private</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">
            </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">void</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DisplayTextFile(
      AbstractFile file )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">{</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      Console.WriteLine( "Displaying the contents of {0}, which is a {1}.", </span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        file.FullName,</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        file.GetType().Name );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">using</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      StreamReader reader = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> StreamReader(
      file.OpenRead() ) )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      {</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">string</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> line;</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">while</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      ( line = reader.ReadLine() ) != </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">null</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        {</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
          Console.WriteLine( line );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        }</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      }</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      Console.WriteLine();</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">}</span>
          </pre>
        </div>
        <!--EndFragment-->
        <br />
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      Displaying the contents of those files is always the same!</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      first );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      second );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      third );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      fourth );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      fifth );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      sixth );</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      And why not finish this demonstration by deleting the files we just created.
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      And finally, deleting files is the same!</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">second.Delete();</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">third.Delete();</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">fourth.Delete();</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">fifth.Delete();</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">sixth.Delete();</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      Any kind of file is an AbstractFile. Any kind of folder is an AbstractFolder. This
      way, a DiskFile, an IsolatedFile, a ZippedFile and a MemoryFile share a common set
      of properties and methods for accessing their metadata and reading/writing their actual
      data. And a DiskFolder, an IsolatedFolder, a ZippedFolder and a MemoryFolder share
      a common set of methods for discovering child items.
   </p>
        <p>
      How does the FTP FileSystem come into play? Simply by offering the same abstraction
      over files and folders stored on an FTP server. We could simply add this code to the
      above sample, and everything works just as expected!
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFile
      seventh = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpFile( </span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpConnection(
      "localhost" ), @"\RemoteFileSystem.txt" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">first.CopyTo(
      seventh, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">DisplayTextFile(
      seventh );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">seventh.Delete();</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      Let's dive a little bit into this implementation of an AbstractFile and AbstractFolder.
      Each constructor requires an FtpConnection instance, which contains information on
      how to connect to the target FTP server. Though it looks like a simple information
      storage class, it does much more. Each time an FtpFile or an FtpFolder requires information,
      or an incoming or outgoing stream on a file's data, it asks the FtpConnection for
      an active command channel connection to the server. This way, a unique command channel
      is generally required for accessing many files on the server.
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">using</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      FtpConnection connection = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpConnection(
      "ftp.xceed.com" ) )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">{</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      connection.TraceWriter = Console.Out;</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      FtpFolder root = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpFolder(
      connection );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">foreach</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      AbstractFile file </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">in</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> root.GetFiles( </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">false</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">,
      "*.txt" ) )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      {</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        DisplayTextFile( file );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      }</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">}</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      If we comment out the "Console.WriteLine( line );" line in "DisplayTextFile", we can
      see the FTP conversation that occurred for the above code:
   </p>
        <p>
        </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">Connected to 66.46.177.250:21 on 9/27/2005 @ 2:24:54 PM<br />
      &lt; 220 Serv-U FTP Server v6.0 for WinSock ready...<br />
      &gt; USER anonymous<br />
      &lt; 331 User name okay, please send complete E-mail address as password.<br />
      &gt; PASS *****<br />
      &lt; 230 User logged in, proceed.<br />
      &gt; PWD<br />
      &lt; 257 "/" is current directory.<br />
      &gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; TYPE A<br />
      &lt; 200 Type set to A.<br />
      &gt; PASV<br />
      &lt; 227 Entering Passive Mode (66,46,177,250,6,238)<br />
      &gt; LIST<br />
      Data connection established with 66.46.177.250:1774 on 9/27/2005 @ 2:24:56 PM<br />
      &lt; 150 Opening ASCII mode data connection for /bin/ls.<br />
      &lt; 226-Maximum disk quota limited to Unlimited kBytes<br />
      &lt; Used disk quota 0 kBytes, available Unlimited kBytes<br />
      &lt; 226 Transfer complete.<br />
      Displaying the contents of \FileSystem.txt, which is a FtpFile.<br />
      &gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; TYPE I<br />
      &lt; 200 Type set to I.<br />
      &gt; PASV<br />
      &lt; 227 Entering Passive Mode (66,46,177,250,6,240)<br />
      &gt; RETR FileSystem.txt<br />
      Data connection established with 66.46.177.250:1776 on 9/27/2005 @ 2:24:57 PM<br />
      &lt; 150 Opening BINARY mode data connection for FileSystem.txt (1198 Bytes).<br />
      &lt; 226-Maximum disk quota limited to Unlimited kBytes<br />
      &lt; Used disk quota 0 kBytes, available Unlimited kBytes<br />
      &lt; 226 Transfer complete.<br /><br />
      Displaying the contents of \appnote.txt, which is a FtpFile.<br />
      &gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; TYPE I<br />
      &lt; 200 Type set to I.<br />
      &gt; PASV<br />
      &lt; 227 Entering Passive Mode (66,46,177,250,6,246)<br />
      &gt; RETR appnote.txt<br />
      Data connection established with 66.46.177.250:1782 on 9/27/2005 @ 2:24:58 PM<br />
      &lt; 150 Opening BINARY mode data connection for appnote.txt (109785 Bytes).<br />
      &lt; 226-Maximum disk quota limited to Unlimited kBytes<br />
      &lt; Used disk quota 0 kBytes, available Unlimited kBytes<br />
      &lt; 226 Transfer complete.<br /><br />
      &gt; QUIT<br />
      Disconnected from 66.46.177.250:21 on 9/27/2005 @ 2:25:04 PM</pre>
        </div>
        <p>
        </p>
        <p>
      Each FtpFolder and FtpFile instance shared the same FtpConnection, and since no two
      operations were done at the same time, a single connection was required, as the log
      indicates. The FtpConnection object implements the IDisposable interface, since it
      keeps any active connection available until disposed (or finalized).
   </p>
        <p>
      Now what happens if I try to open two files at the same time, like this?
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">using</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      FtpConnection connection = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpConnection(
      "ftp.xceed.com" ) )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">{</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      connection.TraceWriter = Console.Out;</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      AbstractFile first = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpFile(
      connection, @"\FileSystem.txt" );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      AbstractFile second = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpFile(
      connection, @"\appnote.txt" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">using</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      Stream firstStream = first.OpenRead() )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      {</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">using</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">(
      Stream secondStream = second.OpenRead() )</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        {</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
          </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      In an FTP conversation with an FTP server, only one command</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
          </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      at a time can be pending. Here, we clearly have two files</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
          </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      open at the same time on the same FTP server. How? Each file</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
          </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      has its own connection to the FTP server!</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
        }</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> 
      }</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">}</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      The FtpConnection object will create extra command channel connections as required. The
      output shows two command channel connections were made:
   </p>
        <p>
        </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <font color="#ff0000">Connected
      to 66.46.177.250:21 on 9/27/2005 @ 2:38:06 PM<br />
      &lt; 220 Serv-U FTP Server v6.0 for WinSock ready...<br />
      &gt; USER anonymous<br />
      &lt; 331 User name okay, please send complete E-mail address as password.<br />
      &gt; PASS *****<br />
      &lt; 230 User logged in, proceed.<br /></font>&gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; TYPE A<br />
      &lt; 200 Type set to A.<br />
      &gt; PASV<br />
      &lt; 227 Entering Passive Mode (66,46,177,250,10,53)<br />
      &gt; LIST<br />
      Data connection established with 66.46.177.250:2613 on 9/27/2005 @ 2:38:07 PM<br />
      &lt; 150 Opening ASCII mode data connection for /bin/ls.<br />
      &lt; 226-Maximum disk quota limited to Unlimited kBytes<br />
      &lt;     Used disk quota 0 kBytes, available Unlimited kBytes<br />
      &lt; 226 Transfer complete.<br />
      &gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; TYPE I<br />
      &lt; 200 Type set to I.<br />
      &gt; PASV<br />
      &lt; 227 Entering Passive Mode (66,46,177,250,10,54)<br />
      &gt; RETR FileSystem.txt<br />
      Data connection established with 66.46.177.250:2614 on 9/27/2005 @ 2:38:08 PM<br />
      &lt; 150 Opening BINARY mode data connection for FileSystem.txt (1198 Bytes).<br />
      Connected to 66.46.177.250:21 on 9/27/2005 @ 2:38:08 PM<br /><font color="#ff0000">&lt; 220 Serv-U FTP Server v6.0 for WinSock ready...<br />
      &gt; USER anonymous<br /></font>&lt; 226-Maximum disk quota limited to Unlimited kBytes<br />
      &lt;     Used disk quota 0 kBytes, available Unlimited kBytes<br />
      &lt; 226 Transfer complete.<br /><font color="#ff0000">&lt; 331 User name okay, please send complete E-mail address
      as password.<br /></font><font color="#ff0000">&gt; PASS *****<br />
      &lt; 230 User logged in, proceed.<br /></font>&gt; CWD /<br />
      &lt; 250 Directory changed to /<br />
      &gt; TYPE I<br />
      &lt; 200 Type set to I.<br />
      &gt; PASV<br />
      &lt; 227 Entering Passive Mode (66,46,177,250,10,55)<br />
      &gt; RETR appnote.txt<br />
      Data connection established with 66.46.177.250:2615 on 9/27/2005 @ 2:38:09 PM<br />
      &lt; 150 Opening BINARY mode data connection for appnote.txt (109785 Bytes).<br />
      &lt; 426-Maximum disk quota limited to Unlimited kBytes<br />
      &lt;     Used disk quota 0 kBytes, available Unlimited kBytes<br />
      &lt; 426 Data connection closed, file transfer appnote.txt aborted.<br /><font color="#ff0000">&gt; QUIT<br />
      Disconnected from 66.46.177.250:21 on 9/27/2005 @ 2:38:13 PM<br />
      &gt; QUIT<br />
      Disconnected from 66.46.177.250:21 on 9/27/2005 @ 2:38:13 PM</font></pre>
        </div>
        <p>
        </p>
        <p>
      And the great part about all this is that you don't have to worry about this while
      coding. You're just manipulating yet another kind of AbstractFile or AbstractFolder.
   </p>
        <p>
      If we get back to the Zip implementation of the Xceed FileSystem, you can see that
      a ZippedFile or ZippedFolder (or ZipArchive, the root ZippedFolder) constructor needs
      to know which AbstractFile is holding the actual zip file that should contain this
      file or folder. "AbstractFile" truly means "any file", as long as there is an AbstractFile-derived
      class somewhere to expose this file. It means that zipping directly onto an FTP server
      is no more difficult than zipping in a regular file on disk.
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFolder
      source = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFolder(
      @"d:\Data" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFolder
      localDest = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> ZipArchive( </span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFile(
      @"d:\temp\local.zip" ) );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFolder
      remoteDest = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> ZipArchive(</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpFile( </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpConnection(
      "localhost" ), @"remote.zip" ) );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      Copying is the same, no matter what is the destination</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      file or folder.</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">source.CopyTo(
      localDest, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">source.CopyTo(
      remoteDest, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> );</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      Code for zipping in "D:\temp\local.zip" is no different than code for zipping in "ftp://localhost/remote.zip".
      And obviously, reading or unzipping from any zip file is the same.
   </p>
        <div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;">
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFolder
      localSource = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> ZipArchive( </span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFile(
      @"d:\temp\local.zip" ) );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFolder
      remoteSource = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> ZipArchive(</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">  </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpFile( </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> FtpConnection(
      "localhost" ), @"remote.zip" ) );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">AbstractFolder
      dest = </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">new</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"> DiskFolder(
      @"d:\restored" );</span>
          </pre>
          <pre style="margin: 0px;"> </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);">//
      Unzipping text files from any source is the same!</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">localSource.CopyFilesTo(
      dest, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">,
      "*.txt" );</span>
          </pre>
          <pre style="margin: 0px;">
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">remoteSource.CopyFilesTo(
      dest, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">, </span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);">true</span>
            <span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;">,
      "*.txt" );</span>
          </pre>
        </div>
        <!--EndFragment-->
        <p>
      I really hope this new addition to the Xceed FileSystem will generate the same enthusiasm
      we had inventing and developping it. I'm very interested in hearing your opinions!
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=78f813ed-96ee-4752-8ab5-2061b0f9d758" />
      </body>
      <title>Xceed FTP FileSystem - Finally released!</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,78f813ed-96ee-4752-8ab5-2061b0f9d758.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,78f813ed-96ee-4752-8ab5-2061b0f9d758.aspx</link>
      <pubDate>Wed, 05 Oct 2005 19:09:39 GMT</pubDate>
      <description>&lt;p&gt;
   I'm glad to announce that Xceed FTP for .NET 2.1 is &lt;a href="http://xceedsoft.com/download/downloadform.aspx?produitID=371"&gt;now
   available for download&lt;/a&gt;. I've been working on this release for the past few months,
   and I'm very excited to finally see the FTP FileSystem come to life.
&lt;/p&gt;
&lt;p&gt;
   For those not familiar with the Xceed FileSystem, which comes with Xceed Zip for .NET,
   here is some code that sheds some light on what you can do with it. Consider these
   variables of the same base type:
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   A file on disk&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   first = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFile(
   @"d:\FileSystem.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   Another file on disk&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   second = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFile(
   @"c:\temp\AnotherFileSystem.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   A file compressed in a zip file on disk&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   third = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; ZippedFile( &lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFile(
   @"c:\temp\data.zip" ), "FileSystemInAZip.txt" );;&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   A file in the isolated storage&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   fourth = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; IsolatedFile(
   "Isolated.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   A file in memory (random name)&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   fifth = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; MemoryFile();&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   A file compressed in a zip file in memory&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   sixth = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; ZippedFile( &lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; MemoryFile(),
   "VolatileFileSystem.txt" );&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   You can copy files around very easily:
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   Copying the first file anywhere else is always the same!&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;first.CopyTo(
   second, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;first.CopyTo(
   third, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;first.CopyTo(
   fourth, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;first.CopyTo(
   fifth, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;first.CopyTo(
   sixth, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   And accessing the contents of any file is always the same:
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;private&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;void&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DisplayTextFile(
   AbstractFile file )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;{&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   Console.WriteLine( "Displaying the contents of {0}, which is a {1}.", &lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; file.FullName,&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; file.GetType().Name );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   StreamReader reader = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; StreamReader(
   file.OpenRead() ) )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   {&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; line;&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;while&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   ( line = reader.ReadLine() ) != &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; {&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &amp;nbsp; Console.WriteLine( line );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; }&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   }&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   Console.WriteLine();&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   Displaying the contents of those files is always the same!&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   first );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   second );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   third );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   fourth );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   fifth );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   sixth );&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   And why not finish this demonstration by deleting the files we just created.
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   And finally, deleting files is the same!&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;second.Delete();&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;third.Delete();&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;fourth.Delete();&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;fifth.Delete();&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;sixth.Delete();&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   Any kind of file is an AbstractFile. Any kind of folder is an AbstractFolder. This
   way, a DiskFile, an IsolatedFile, a ZippedFile and a MemoryFile share a common set
   of properties and methods for accessing their metadata and reading/writing their actual
   data. And a DiskFolder, an IsolatedFolder, a ZippedFolder and a MemoryFolder share
   a common set of methods for discovering child items.
&lt;/p&gt;
&lt;p&gt;
   How does the FTP FileSystem come into play? Simply by offering the same abstraction
   over files and folders stored on an FTP server. We could simply add this code to the
   above sample, and everything works just as expected!
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFile
   seventh = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpFile( &lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpConnection(
   "localhost" ), @"\RemoteFileSystem.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;first.CopyTo(
   seventh, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;DisplayTextFile(
   seventh );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;seventh.Delete();&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   Let's dive a little bit into this implementation of an AbstractFile and AbstractFolder.
   Each constructor requires an FtpConnection instance, which contains information on
   how to connect to the target FTP server. Though it looks like a simple information
   storage class, it does much more. Each time an FtpFile or an FtpFolder requires information,
   or an incoming or outgoing stream on a file's data, it asks the FtpConnection for
   an active command channel connection to the server. This way, a unique command channel
   is generally required for accessing many files on the server.
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   FtpConnection connection = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpConnection(
   "ftp.xceed.com" ) )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;{&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   connection.TraceWriter = Console.Out;&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   FtpFolder root = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpFolder(
   connection );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   AbstractFile file &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;in&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; root.GetFiles( &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;,
   "*.txt" ) )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   {&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; DisplayTextFile( file );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   }&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   If we comment out the "Console.WriteLine( line );" line in "DisplayTextFile", we can
   see the FTP conversation that occurred for the above code:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;Connected to 66.46.177.250:21 on 9/27/2005 @ 2:24:54 PM&lt;br&gt;
   &amp;lt; 220 Serv-U FTP Server v6.0 for WinSock ready...&lt;br&gt;
   &amp;gt; USER anonymous&lt;br&gt;
   &amp;lt; 331 User name okay, please send complete E-mail address as password.&lt;br&gt;
   &amp;gt; PASS *****&lt;br&gt;
   &amp;lt; 230 User logged in, proceed.&lt;br&gt;
   &amp;gt; PWD&lt;br&gt;
   &amp;lt; 257 "/" is current directory.&lt;br&gt;
   &amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; TYPE A&lt;br&gt;
   &amp;lt; 200 Type set to A.&lt;br&gt;
   &amp;gt; PASV&lt;br&gt;
   &amp;lt; 227 Entering Passive Mode (66,46,177,250,6,238)&lt;br&gt;
   &amp;gt; LIST&lt;br&gt;
   Data connection established with 66.46.177.250:1774 on 9/27/2005 @ 2:24:56 PM&lt;br&gt;
   &amp;lt; 150 Opening ASCII mode data connection for /bin/ls.&lt;br&gt;
   &amp;lt; 226-Maximum disk quota limited to Unlimited kBytes&lt;br&gt;
   &amp;lt; Used disk quota 0 kBytes, available Unlimited kBytes&lt;br&gt;
   &amp;lt; 226 Transfer complete.&lt;br&gt;
   Displaying the contents of \FileSystem.txt, which is a FtpFile.&lt;br&gt;
   &amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; TYPE I&lt;br&gt;
   &amp;lt; 200 Type set to I.&lt;br&gt;
   &amp;gt; PASV&lt;br&gt;
   &amp;lt; 227 Entering Passive Mode (66,46,177,250,6,240)&lt;br&gt;
   &amp;gt; RETR FileSystem.txt&lt;br&gt;
   Data connection established with 66.46.177.250:1776 on 9/27/2005 @ 2:24:57 PM&lt;br&gt;
   &amp;lt; 150 Opening BINARY mode data connection for FileSystem.txt (1198 Bytes).&lt;br&gt;
   &amp;lt; 226-Maximum disk quota limited to Unlimited kBytes&lt;br&gt;
   &amp;lt; Used disk quota 0 kBytes, available Unlimited kBytes&lt;br&gt;
   &amp;lt; 226 Transfer complete.&lt;br&gt;
   &lt;br&gt;
   Displaying the contents of \appnote.txt, which is a FtpFile.&lt;br&gt;
   &amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; TYPE I&lt;br&gt;
   &amp;lt; 200 Type set to I.&lt;br&gt;
   &amp;gt; PASV&lt;br&gt;
   &amp;lt; 227 Entering Passive Mode (66,46,177,250,6,246)&lt;br&gt;
   &amp;gt; RETR appnote.txt&lt;br&gt;
   Data connection established with 66.46.177.250:1782 on 9/27/2005 @ 2:24:58 PM&lt;br&gt;
   &amp;lt; 150 Opening BINARY mode data connection for appnote.txt (109785 Bytes).&lt;br&gt;
   &amp;lt; 226-Maximum disk quota limited to Unlimited kBytes&lt;br&gt;
   &amp;lt; Used disk quota 0 kBytes, available Unlimited kBytes&lt;br&gt;
   &amp;lt; 226 Transfer complete.&lt;br&gt;
   &lt;br&gt;
   &amp;gt; QUIT&lt;br&gt;
   Disconnected from 66.46.177.250:21 on 9/27/2005 @ 2:25:04 PM&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
   Each FtpFolder and FtpFile instance shared the same FtpConnection, and since no two
   operations were done at the same time, a single connection was required, as the log
   indicates. The FtpConnection object implements the IDisposable interface, since it
   keeps any active connection available until disposed (or finalized).
&lt;/p&gt;
&lt;p&gt;
   Now what happens if I try to open two files at the same time, like this?
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   FtpConnection connection = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpConnection(
   "ftp.xceed.com" ) )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;{&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   connection.TraceWriter = Console.Out;&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   AbstractFile first = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpFile(
   connection, @"\FileSystem.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   AbstractFile second = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpFile(
   connection, @"\appnote.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   Stream firstStream = first.OpenRead() )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   {&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;using&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;(
   Stream secondStream = second.OpenRead() )&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; {&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   In an FTP conversation with an FTP server, only one command&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   at a time can be pending. Here, we clearly have two files&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   open at the same time on the same FTP server. How? Each file&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   has its own connection to the FTP server!&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   &amp;nbsp; }&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp;
   }&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   The FtpConnection object will create extra command channel connections as required.&amp;nbsp;The
   output shows two command channel connections were made:
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;font color="#ff0000"&gt;Connected
   to 66.46.177.250:21 on 9/27/2005 @ 2:38:06 PM&lt;br&gt;
   &amp;lt; 220 Serv-U FTP Server v6.0 for WinSock ready...&lt;br&gt;
   &amp;gt; USER anonymous&lt;br&gt;
   &amp;lt; 331 User name okay, please send complete E-mail address as password.&lt;br&gt;
   &amp;gt; PASS *****&lt;br&gt;
   &amp;lt; 230 User logged in, proceed.&lt;br&gt;
   &lt;/font&gt;&amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; TYPE A&lt;br&gt;
   &amp;lt; 200 Type set to A.&lt;br&gt;
   &amp;gt; PASV&lt;br&gt;
   &amp;lt; 227 Entering Passive Mode (66,46,177,250,10,53)&lt;br&gt;
   &amp;gt; LIST&lt;br&gt;
   Data connection established with 66.46.177.250:2613 on 9/27/2005 @ 2:38:07 PM&lt;br&gt;
   &amp;lt; 150 Opening ASCII mode data connection for /bin/ls.&lt;br&gt;
   &amp;lt; 226-Maximum disk quota limited to Unlimited kBytes&lt;br&gt;
   &amp;lt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Used disk quota 0 kBytes, available Unlimited kBytes&lt;br&gt;
   &amp;lt; 226 Transfer complete.&lt;br&gt;
   &amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; TYPE I&lt;br&gt;
   &amp;lt; 200 Type set to I.&lt;br&gt;
   &amp;gt; PASV&lt;br&gt;
   &amp;lt; 227 Entering Passive Mode (66,46,177,250,10,54)&lt;br&gt;
   &amp;gt; RETR FileSystem.txt&lt;br&gt;
   Data connection established with 66.46.177.250:2614 on 9/27/2005 @ 2:38:08 PM&lt;br&gt;
   &amp;lt; 150 Opening BINARY mode data connection for FileSystem.txt (1198 Bytes).&lt;br&gt;
   Connected to 66.46.177.250:21 on 9/27/2005 @ 2:38:08 PM&lt;br&gt;
   &lt;font color="#ff0000"&gt;&amp;lt; 220 Serv-U FTP Server v6.0 for WinSock ready...&lt;br&gt;
   &amp;gt; USER anonymous&lt;br&gt;
   &lt;/font&gt;&amp;lt; 226-Maximum disk quota limited to Unlimited kBytes&lt;br&gt;
   &amp;lt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Used disk quota 0 kBytes, available Unlimited kBytes&lt;br&gt;
   &amp;lt; 226 Transfer complete.&lt;br&gt;
   &lt;font color="#ff0000"&gt;&amp;lt; 331 User name okay, please send complete E-mail address
   as password.&lt;br&gt;
   &lt;/font&gt;&lt;font color="#ff0000"&gt;&amp;gt; PASS *****&lt;br&gt;
   &amp;lt; 230 User logged in, proceed.&lt;br&gt;
   &lt;/font&gt;&amp;gt; CWD /&lt;br&gt;
   &amp;lt; 250 Directory changed to /&lt;br&gt;
   &amp;gt; TYPE I&lt;br&gt;
   &amp;lt; 200 Type set to I.&lt;br&gt;
   &amp;gt; PASV&lt;br&gt;
   &amp;lt; 227 Entering Passive Mode (66,46,177,250,10,55)&lt;br&gt;
   &amp;gt; RETR appnote.txt&lt;br&gt;
   Data connection established with 66.46.177.250:2615 on 9/27/2005 @ 2:38:09 PM&lt;br&gt;
   &amp;lt; 150 Opening BINARY mode data connection for appnote.txt (109785 Bytes).&lt;br&gt;
   &amp;lt; 426-Maximum disk quota limited to Unlimited kBytes&lt;br&gt;
   &amp;lt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Used disk quota 0 kBytes, available Unlimited kBytes&lt;br&gt;
   &amp;lt; 426 Data connection closed, file transfer appnote.txt aborted.&lt;br&gt;
   &lt;font color="#ff0000"&gt;&amp;gt; QUIT&lt;br&gt;
   Disconnected from 66.46.177.250:21 on 9/27/2005 @ 2:38:13 PM&lt;br&gt;
   &amp;gt; QUIT&lt;br&gt;
   Disconnected from 66.46.177.250:21 on 9/27/2005 @ 2:38:13 PM&lt;/font&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
   And the great part about all this is that you don't have to worry about this while
   coding. You're just manipulating yet another kind of AbstractFile or AbstractFolder.
&lt;/p&gt;
&lt;p&gt;
   If we get back to the Zip implementation of the Xceed FileSystem, you can see that
   a ZippedFile or ZippedFolder (or ZipArchive, the root ZippedFolder) constructor needs
   to know which AbstractFile is holding the actual zip file that should contain this
   file or folder. "AbstractFile" truly means "any file", as long as there is an AbstractFile-derived
   class somewhere to expose this file. It means that zipping directly onto an FTP server
   is no more difficult than zipping in a regular file on disk.
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFolder
   source = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFolder(
   @"d:\Data" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFolder
   localDest = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; ZipArchive( &lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFile(
   @"d:\temp\local.zip" ) );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFolder
   remoteDest = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; ZipArchive(&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpFile( &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpConnection(
   "localhost" ), @"remote.zip" ) );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   Copying is the same, no matter what is the destination&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   file or folder.&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;source.CopyTo(
   localDest, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;source.CopyTo(
   remoteDest, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; );&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   Code for zipping in "D:\temp\local.zip" is no different than code for zipping in "ftp://localhost/remote.zip".
   And obviously, reading or unzipping from any zip file is the same.
&lt;/p&gt;
&lt;div style="border: 1pt solid windowtext; padding: 0pt; background: rgb(255, 255, 255) none repeat scroll 0%; font-size: 8pt; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 0); font-family: Courier New;"&gt;&lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFolder
   localSource = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; ZipArchive( &lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFile(
   @"d:\temp\local.zip" ) );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFolder
   remoteSource = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; ZipArchive(&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;&amp;nbsp; &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpFile( &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; FtpConnection(
   "localhost" ), @"remote.zip" ) );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;AbstractFolder
   dest = &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;new&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt; DiskFolder(
   @"d:\restored" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 128, 0);"&gt;//
   Unzipping text files from any source is the same!&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;localSource.CopyFilesTo(
   dest, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;,
   "*.txt" );&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="margin: 0px;"&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;remoteSource.CopyFilesTo(
   dest, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;, &lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;&lt;span style="background: rgb(255, 255, 255) none repeat scroll 0%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"&gt;,
   "*.txt" );&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   I really hope this new addition to the Xceed FileSystem will generate the same enthusiasm
   we had inventing and developping it. I'm very interested in hearing your opinions!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=78f813ed-96ee-4752-8ab5-2061b0f9d758" /&gt;</description>
      <category>.NET;FileSystem;FTP;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=3499ec57-b919-494a-bd6a-75b087969ee2</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,3499ec57-b919-494a-bd6a-75b087969ee2.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      I'm currently working hard on the FileSystem support for Xceed FTP for .NET, and I
      had to share with you a screenshot of one of my tests. My XceedBox.NET sample is now
      fully supporting FtpFile and FtpFolder mapping.
   </p>
        <p>
          <img height="443" alt="XceedBoxNET.png" src="http://blogs.xceedsoft.com/plantem/content/binary/XceedBoxNET.png" width="652" border="0" />
        </p>
        <p>
      As you can see, my working folder is a zip file located in a folder on an FTP server.
      The "type" command above has no idea what kind of file it is displaying. It receives
      an AbstractFile, gets a Stream on it via OpenRead, reads and displays the contents.
      That AbstractFile is actually a ZippedFile found in a ZippedFolder constructed
      around an FtpFile found in an FtpFolder.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=3499ec57-b919-494a-bd6a-75b087969ee2" />
      </body>
      <title>The FTP FileSystem is coming</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,3499ec57-b919-494a-bd6a-75b087969ee2.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,3499ec57-b919-494a-bd6a-75b087969ee2.aspx</link>
      <pubDate>Thu, 14 Jul 2005 20:04:21 GMT</pubDate>
      <description>&lt;p&gt;
   I'm currently working hard on the FileSystem support for Xceed FTP for .NET, and I
   had to share with you a screenshot of one of my tests. My XceedBox.NET sample is now
   fully supporting FtpFile and FtpFolder mapping.
&lt;/p&gt;
&lt;p&gt;
   &lt;img height=443 alt=XceedBoxNET.png src="http://blogs.xceedsoft.com/plantem/content/binary/XceedBoxNET.png" width=652 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
   As you can see, my working folder is a zip file located in a folder on an FTP server.
   The "type" command above has no idea what kind of file it is displaying. It receives
   an AbstractFile, gets a Stream on it via OpenRead, reads and displays the contents.
   That AbstractFile is actually a ZippedFile&amp;nbsp;found in a ZippedFolder constructed
   around an FtpFile found in an FtpFolder.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=3499ec57-b919-494a-bd6a-75b087969ee2" /&gt;</description>
      <category>.NET;FileSystem;FTP</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=4fc3e00e-646e-48bf-8dc2-8e7f1df58fa1</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,4fc3e00e-646e-48bf-8dc2-8e7f1df58fa1.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Customer requests come in waves, as if fashion was driving the development industry.
      Lately, many customers were trying to compress log files. I've deviced it was time
      for a little sample.
   </p>
        <p>
      The idea was to encode each string message in unicode and compress it in a plain
      file, one after the other. I could have used a zip file with each file entry representing
      a message, but for small messages, the zip headers would take too much space for nothing,
      wasting the need for compression in the first place.
   </p>
        <p>
      The deflate compression method has one nice feature: it can detect the end of the
      compressed data while decompressing, without knowing the total compressed size. That's
      why the <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.html">CompressedStream</a> class
      exposes a <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.getremainingstream.html">GetRemainingStream</a> method
      for retrieving a Stream reference on the rest of the data in the inner stream.
   </p>
        <p>
      I've kept the sample real simple, so you get the general idea:
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">
            <span style="COLOR: #0000ff">using</span> System;</pre>
          <pre style="MARGIN: 0px">
            <span style="COLOR: #0000ff">using</span> System.IO;</pre>
          <pre style="MARGIN: 0px">
            <span style="COLOR: #0000ff">using</span> Xceed.Compression;</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">
            <span style="COLOR: #0000ff">namespace</span> CompressedLogExample</pre>
          <pre style="MARGIN: 0px">{</pre>
          <pre style="MARGIN: 0px">  <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">class</span> CompressedLog</pre>
          <pre style="MARGIN: 0px">  {</pre>
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">public</span> CompressedLog( <span style="COLOR: #0000ff">string</span> filename
      )</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">if</span>(
      filename == <span style="COLOR: #0000ff">null</span> )</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">throw</span><span style="COLOR: #0000ff">new</span> ArgumentNullException(
      "filename" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">if</span>(
      filename.Length == 0 )</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">throw</span><span style="COLOR: #0000ff">new</span> ArgumentException(
      "The filename cannot be empty.", "filename" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      Xceed.Compression.Licenser.LicenseKey = "SAMPLE-APPLICATION-KEY";</pre>
          <pre style="MARGIN: 0px">      m_filename = filename;</pre>
          <pre style="MARGIN: 0px">    }</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">void</span> AddMessage( <span style="COLOR: #0000ff">string</span> message
      )</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">if</span>(
      message == <span style="COLOR: #0000ff">null</span> )</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">throw</span><span style="COLOR: #0000ff">new</span> ArgumentNullException(
      "message" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">lock</span>(
      m_lock )</pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">using</span>(
      Stream fileStream = <span style="COLOR: #0000ff">new</span> FileStream( m_filename,
      FileMode.Append ) )</pre>
          <pre style="MARGIN: 0px">        {</pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">using</span>(
      CompressedStream compStream = <span style="COLOR: #0000ff">new</span> CompressedStream(
      fileStream ) )</pre>
          <pre style="MARGIN: 0px">          {</pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">byte</span>[]
      encodedMessage = System.Text.Encoding.Unicode.GetBytes(</pre>
          <pre style="MARGIN: 0px">              DateTime.Now.ToString() + Environment.NewLine + message );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">            compStream.Write( encodedMessage, 0, encodedMessage.Length );</pre>
          <pre style="MARGIN: 0px">          }</pre>
          <pre style="MARGIN: 0px">        }</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px">    }</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">void</span> DisplayMessages(
      TextWriter writer )</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">if</span>(
      writer == <span style="COLOR: #0000ff">null</span> )</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">throw</span><span style="COLOR: #0000ff">new</span> ArgumentNullException(
      "writer" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">lock</span>(
      m_lock )</pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">try</span></pre>
          <pre style="MARGIN: 0px">        {</pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">using</span>(
      Stream originalStream = <span style="COLOR: #0000ff">new</span> FileStream( m_filename,
      FileMode.Open ) )</pre>
          <pre style="MARGIN: 0px">          {</pre>
          <pre style="MARGIN: 0px">            Stream workStream = originalStream;</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">do</span></pre>
          <pre style="MARGIN: 0px">            {</pre>
          <pre style="MARGIN: 0px">              <span style="COLOR: #0000ff">using</span>(
      CompressedStream compStream = <span style="COLOR: #0000ff">new</span> CompressedStream(
      workStream ) )</pre>
          <pre style="MARGIN: 0px">              {</pre>
          <pre style="MARGIN: 0px">                <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      We don't want compStream to close sourceStream!</span></pre>
          <pre style="MARGIN: 0px">                compStream.Transient = <span style="COLOR: #0000ff">true</span>;</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">                <span style="COLOR: #0000ff">using</span>(
      StreamReader reader = <span style="COLOR: #0000ff">new</span> StreamReader( </pre>
          <pre style="MARGIN: 0px">                         compStream, System.Text.Encoding.Unicode ) )</pre>
          <pre style="MARGIN: 0px">                {</pre>
          <pre style="MARGIN: 0px">                  writer.WriteLine( reader.ReadToEnd() );</pre>
          <pre style="MARGIN: 0px">                  writer.WriteLine( "---" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">                  <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      Before closing the reader (thus compStream), acquire a stream on</span></pre>
          <pre style="MARGIN: 0px">                  <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      the rest of the data if present.</span></pre>
          <pre style="MARGIN: 0px">                  workStream = compStream.GetRemainingStream();</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">                  <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      We must do this AFTER calling GetRemainingStream since compStream</span></pre>
          <pre style="MARGIN: 0px">                  <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      may have read more from its inner stream than necessary.</span></pre>
          <pre style="MARGIN: 0px">                  <span style="COLOR: #0000ff">if</span>(
      workStream.Position == workStream.Length )</pre>
          <pre style="MARGIN: 0px">                  {</pre>
          <pre style="MARGIN: 0px">                    workStream = <span style="COLOR: #0000ff">null</span>;</pre>
          <pre style="MARGIN: 0px">                  }</pre>
          <pre style="MARGIN: 0px">                }</pre>
          <pre style="MARGIN: 0px">              }</pre>
          <pre style="MARGIN: 0px">            }</pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">while</span>(
      workStream != <span style="COLOR: #0000ff">null</span> );</pre>
          <pre style="MARGIN: 0px">          }</pre>
          <pre style="MARGIN: 0px">        }</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">catch</span>(
      FileNotFoundException )</pre>
          <pre style="MARGIN: 0px">        {</pre>
          <pre style="MARGIN: 0px">          writer.WriteLine( "The log is empty." );</pre>
          <pre style="MARGIN: 0px">        }</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px">    }</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">private</span><span style="COLOR: #0000ff">string</span> m_filename
      = <span style="COLOR: #0000ff">string</span>.Empty;</pre>
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">private</span><span style="COLOR: #0000ff">object</span> m_lock
      = <span style="COLOR: #0000ff">new</span><span style="COLOR: #0000ff">object</span>();</pre>
          <pre style="MARGIN: 0px">  }</pre>
          <pre style="MARGIN: 0px">}</pre>
        </div>
        <p>
      Unfortunately, you can't replace the CompressedStream with a formatted stream
      like <a href="http://doc.xceedsoft.com/products/streamNet/ref/xceed.compression.formats.gzipcompressedstream.html">GZipCompressedStream</a>,
      because they do not expose a GetRemainingStream method yet. Too bad, since the GZipCompressedStream
      can store a few minimal informations in its header. I'll have to open a feature request
      about that!
   </p>
        <p>
      Here is some sample code for using this CompressedLog class:
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">static</span><span style="COLOR: #0000ff">void</span> Main(<span style="COLOR: #0000ff">string</span>[]
      args)</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      CompressedLog log = <span style="COLOR: #0000ff">new</span> CompressedLog(
      @"d:\temp\log.cmp" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">while</span>( <span style="COLOR: #0000ff">true</span> )</pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        Console.WriteLine( "Write your next message below (empty message to quit):" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">string</span> line
      = Console.ReadLine();</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">if</span>(
      line.Length == 0 )</pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">break</span>;</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        log.AddMessage( line );</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      Console.WriteLine();</pre>
          <pre style="MARGIN: 0px">      Console.WriteLine( "Your messages were:" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      log.DisplayMessages( Console.Out );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      Console.WriteLine( "Press &lt;Enter&gt; to quit." );</pre>
          <pre style="MARGIN: 0px">      Console.ReadLine();</pre>
          <pre style="MARGIN: 0px">    }</pre>
        </div>
        <!--EndFragment-->
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=4fc3e00e-646e-48bf-8dc2-8e7f1df58fa1" />
      </body>
      <title>Compressed log files</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,4fc3e00e-646e-48bf-8dc2-8e7f1df58fa1.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,4fc3e00e-646e-48bf-8dc2-8e7f1df58fa1.aspx</link>
      <pubDate>Thu, 16 Jun 2005 19:04:00 GMT</pubDate>
      <description>&lt;p&gt;
   Customer requests come in waves, as if fashion was driving the development industry.
   Lately, many customers were trying to compress log files. I've deviced it was time
   for a little sample.
&lt;/p&gt;
&lt;p&gt;
   The idea was to encode each string message in unicode&amp;nbsp;and compress it in a plain
   file, one after the other. I could have used a zip file with each file entry representing
   a message, but for small messages, the zip headers would take too much space for nothing,
   wasting the need for compression in the first place.
&lt;/p&gt;
&lt;p&gt;
   The deflate compression method has one nice feature: it can detect the end of the
   compressed data while decompressing, without knowing the total compressed size. That's
   why the &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.html"&gt;CompressedStream&lt;/a&gt; class
   exposes a &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.compression.compressedstream.getremainingstream.html"&gt;GetRemainingStream&lt;/a&gt; method
   for retrieving a Stream reference on the rest of the data in the inner stream.
&lt;/p&gt;
&lt;p&gt;
   I've kept the sample real simple, so you get the general idea:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt; System;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt; System.IO;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt; Xceed.Compression;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&lt;span style="COLOR: #0000ff"&gt;namespace&lt;/span&gt; CompressedLogExample&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;{&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;class&lt;/span&gt; CompressedLog&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; CompressedLog( &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; filename
   )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   filename == &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt; )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ArgumentNullException(
   "filename" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   filename.Length == 0 )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ArgumentException(
   "The filename cannot be empty.", "filename" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Xceed.Compression.Licenser.LicenseKey = "SAMPLE-APPLICATION-KEY";&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; m_filename = filename;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; AddMessage( &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; message
   )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   message == &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt; )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ArgumentNullException(
   "message" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;lock&lt;/span&gt;(
   m_lock )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   Stream fileStream = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; FileStream( m_filename,
   FileMode.Append ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   CompressedStream compStream = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; CompressedStream(
   fileStream ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;byte&lt;/span&gt;[]
   encodedMessage = System.Text.Encoding.Unicode.GetBytes(&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DateTime.Now.ToString() + Environment.NewLine + message );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; compStream.Write( encodedMessage, 0, encodedMessage.Length );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; DisplayMessages(
   TextWriter writer )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   writer == &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt; )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ArgumentNullException(
   "writer" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;lock&lt;/span&gt;(
   m_lock )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;try&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   Stream originalStream = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; FileStream( m_filename,
   FileMode.Open ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Stream workStream = originalStream;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;do&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   CompressedStream compStream = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; CompressedStream(
   workStream ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   We don't want compStream to close sourceStream!&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; compStream.Transient = &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   StreamReader reader = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; StreamReader( &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  compStream, System.Text.Encoding.Unicode ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; writer.WriteLine( reader.ReadToEnd() );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; writer.WriteLine( "---" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   Before closing the reader (thus compStream), acquire a stream on&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   the rest of the data if present.&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; workStream = compStream.GetRemainingStream();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   We must do this AFTER calling GetRemainingStream since compStream&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   may have read more from its inner stream than necessary.&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   workStream.Position == workStream.Length )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; workStream = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;while&lt;/span&gt;(
   workStream != &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt; );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;catch&lt;/span&gt;(
   FileNotFoundException )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; writer.WriteLine( "The log is empty." );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; m_filename
   = &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;.Empty;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt; m_lock
   = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt;();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;}&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
   Unfortunately, you can't replace the CompressedStream&amp;nbsp;with a formatted stream
   like &lt;a href="http://doc.xceedsoft.com/products/streamNet/ref/xceed.compression.formats.gzipcompressedstream.html"&gt;GZipCompressedStream&lt;/a&gt;,
   because they do not expose a GetRemainingStream method yet. Too bad, since the GZipCompressedStream
   can store a few minimal informations in its header. I'll have to open a feature request
   about that!
&lt;/p&gt;
&lt;p&gt;
   Here is some sample code for using this CompressedLog class:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; Main(&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;[]
   args)&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; CompressedLog log = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; CompressedLog(
   @"d:\temp\log.cmp" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;while&lt;/span&gt;( &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt; )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine( "Write your next message below (empty message to quit):" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; line
   = Console.ReadLine();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   line.Length == 0 )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; log.AddMessage( line );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine( "Your messages were:" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; log.DisplayMessages( Console.Out );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Console.WriteLine( "Press &amp;lt;Enter&amp;gt; to quit." );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Console.ReadLine();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=4fc3e00e-646e-48bf-8dc2-8e7f1df58fa1" /&gt;</description>
      <category>.NET;Samples</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      In the new package v1.2.5309 which will be <a href="http://www.xceedsoft.com/download/updates.aspx">available
      for download</a> next week resides a new feature you won't see much emphasis
      about, but which I was very eager to complete. You can now create a <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.zip.ziparchive.html">ZipArchive</a> instance
      around an AbstractFile that does not support reading from.
   </p>
        <p>
      (drum roll) ... (looking around) ... Nobody's applauding? That's because you probably
      don't know yet how useful this can be.
   </p>
        <p>
      Most ASP.NET applications that wish to create zip files on the fly and send them in
      the response are either stuck with creating those zip files on disk in a temporary
      filename, or create them in a <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.memoryfile.html">MemoryFile</a>,
      then copy that MemoryFile in the response stream.
   </p>
        <p>
      However, the <a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.streamfile.html">StreamFile</a> class
      was created for such purposes of exposing any existing Stream as an AbstractFile.
      You already could create a StreamFile around the <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpresponseclasstopic.asp">Response</a>'s <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpresponseclassoutputstreamtopic.asp">OutputStream</a>.
      But passing that StreamFile to the ZipArchive's constructor would fail, because it
      can't read from it. Instead of assuming an empty zip file, it miserably failed. Shame.
   </p>
        <p>
      No more... Since version 2.2.5302, it will assume the zip file is empty. So code like
      this works perfectly:
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">public</span><span style="COLOR: #0000ff">void</span> ProcessRequest(HttpContext
      context)</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      context.Response.ContentType = "application/zip";</pre>
          <pre style="MARGIN: 0px">      context.Response.AddHeader( "Content-Disposition", "attachment; filename=images.bmp" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      ZipArchive archive = <span style="COLOR: #0000ff">new</span> ZipArchive( <span style="COLOR: #0000ff">new</span> StreamFile(
      context.Response.OutputStream ) );</pre>
          <pre style="MARGIN: 0px">      DiskFolder source = <span style="COLOR: #0000ff">new</span> DiskFolder(
      context.Request.MapPath( "." ) );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      source.CopyFilesTo( archive, <span style="COLOR: #0000ff">false</span>, <span style="COLOR: #0000ff">false</span>,
      "*.bmp" );</pre>
          <pre style="MARGIN: 0px">    }</pre>
        </div>
        <!--EndFragment-->
        <p>
      The same problem appeared when trying to combine <a href="http://www.xceedsoft.com/products/ZipNet/index.aspx">Xceed
      Zip for .NET</a> with <a href="http://www.xceedsoft.com/products/FtpNet/index.aspx">Xceed
      FTP for .NET</a>, to upload zip files directly on the FTP server. Though the <a href="http://doc.xceedsoft.com/products/ftpNet/ref/xceed.ftp.ftpclient.html">FtpClient</a> class
      exposes a very useful <a href="http://doc.xceedsoft.com/products/ftpNet/ref/xceed.ftp.ftpclient.getuploadstream_overloads.html">GetUploadStream</a> method
      to get a direct stream on the data connection, code like this previously failed.
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">using</span>(
      Stream upload = client.GetUploadStream( "images.zip" ) )</pre>
          <pre style="MARGIN: 0px">          {</pre>
          <pre style="MARGIN: 0px">            ZipArchive archive = <span style="COLOR: #0000ff">new</span> ZipArchive( <span style="COLOR: #0000ff">new</span> StreamFile(
      upload ) );</pre>
          <pre style="MARGIN: 0px">            DiskFolder source = <span style="COLOR: #0000ff">new</span> DiskFolder(
      @"d:\images\" );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">            source.CopyFilesTo( archive, <span style="COLOR: #0000ff">false</span>, <span style="COLOR: #0000ff">false</span>,
      "*.bmp" );</pre>
          <pre style="MARGIN: 0px">          }</pre>
        </div>
        <!--EndFragment-->
        <p>
      Talk about short and sweet uploads of zip files!<!--StartFragment --></p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3" />
      </body>
      <title>Zipping from ASP.NET or to an FTP server</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3.aspx</link>
      <pubDate>Thu, 09 Jun 2005 18:56:43 GMT</pubDate>
      <description>&lt;p&gt;
   In the new package v1.2.5309 which will be&amp;nbsp;&lt;a href="http://www.xceedsoft.com/download/updates.aspx"&gt;available
   for download&lt;/a&gt;&amp;nbsp;next week&amp;nbsp;resides a new feature you won't see much emphasis
   about, but which I was very eager to complete. You can now create a &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.zip.ziparchive.html"&gt;ZipArchive&lt;/a&gt; instance
   around an AbstractFile that does not support reading from.
&lt;/p&gt;
&lt;p&gt;
   (drum roll) ... (looking around) ... Nobody's applauding? That's because you probably
   don't know yet how useful this can be.
&lt;/p&gt;
&lt;p&gt;
   Most ASP.NET applications that wish to create zip files on the fly and send them in
   the response are either stuck with creating those zip files on disk in a temporary
   filename, or create them in a &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.memoryfile.html"&gt;MemoryFile&lt;/a&gt;,
   then copy that MemoryFile in the response stream.
&lt;/p&gt;
&lt;p&gt;
   However, the &lt;a href="http://doc.xceedsoft.com/products/zipNet/ref/xceed.filesystem.streamfile.html"&gt;StreamFile&lt;/a&gt; class
   was created for such purposes of exposing any existing Stream as an AbstractFile.
   You already could create a StreamFile around the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpresponseclasstopic.asp"&gt;Response&lt;/a&gt;'s &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpresponseclassoutputstreamtopic.asp"&gt;OutputStream&lt;/a&gt;.
   But passing that StreamFile to the ZipArchive's constructor would fail, because it
   can't read from it. Instead of assuming an empty zip file, it miserably failed. Shame.
&lt;/p&gt;
&lt;p&gt;
   No more... Since version 2.2.5302, it will assume the zip file is empty. So code like
   this works perfectly:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; ProcessRequest(HttpContext
   context)&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; context.Response.ContentType = "application/zip";&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; context.Response.AddHeader( "Content-Disposition", "attachment; filename=images.bmp" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; ZipArchive archive = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ZipArchive( &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; StreamFile(
   context.Response.OutputStream ) );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; DiskFolder source = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; DiskFolder(
   context.Request.MapPath( "." ) );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; source.CopyFilesTo( archive, &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;,
   "*.bmp" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   The same problem appeared when trying to combine &lt;a href="http://www.xceedsoft.com/products/ZipNet/index.aspx"&gt;Xceed
   Zip for .NET&lt;/a&gt; with &lt;a href="http://www.xceedsoft.com/products/FtpNet/index.aspx"&gt;Xceed
   FTP for .NET&lt;/a&gt;, to upload zip files directly on the FTP server. Though the &lt;a href="http://doc.xceedsoft.com/products/ftpNet/ref/xceed.ftp.ftpclient.html"&gt;FtpClient&lt;/a&gt; class
   exposes a very useful &lt;a href="http://doc.xceedsoft.com/products/ftpNet/ref/xceed.ftp.ftpclient.getuploadstream_overloads.html"&gt;GetUploadStream&lt;/a&gt; method
   to get a direct stream on the data connection, code like this previously failed.
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   Stream upload = client.GetUploadStream( "images.zip" ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ZipArchive archive = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ZipArchive( &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; StreamFile(
   upload ) );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DiskFolder source = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; DiskFolder(
   @"d:\images\" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; source.CopyFilesTo( archive, &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;,
   "*.bmp" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   Talk about short and sweet uploads of zip files!&lt;!--StartFragment --&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=5bba8ded-a7b0-40ce-ae9f-33b3c3cbb4e3" /&gt;</description>
      <category>.NET;FileSystem;FTP;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=cff8fc14-76a1-4fde-a4f0-a49ab582a21a</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,cff8fc14-76a1-4fde-a4f0-a49ab582a21a.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      Lately, people have been asking us how to abort a zipping operation with Xceed Zip
      for .NET. The official answer is "you can't", as there is no method or property exposed
      for this task, as opposed to Xceed Zip ActiveX with its simple Abort property. But
      the truth is you can, with relatively little coding.
   </p>
        <p>
      Before we get into how to abort, let's talk a little bit about the ZipArchive's TempFolder
      property. By default, it points to the same folder as the static ZipArchive.DefaultTempFolder
      property, which itself points to the user's temp folder, as exposed by System.IO.Path.GetTempPath().
   </p>
        <p>
      Though the library is designed to delete any file it creates in the temporary folder,
      this can occur only when instances get finalized if the operation failed in the middle
      of the process.
   </p>
        <p>
      A good coding pattern I like to use is the following:
   </p>
        <pre style="MARGIN: 0px">
          <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
            <pre style="MARGIN: 0px">    ZipArchive zip = <span style="COLOR: #0000ff">new</span> ZipArchive( <span style="COLOR: #0000ff">new</span> DiskFile(
      @"d:\temp\backup.zip" ) );</pre>
            <pre style="MARGIN: 0px">    zip.TempFolder = zip.TempFolder.CreateFolder( Guid.NewGuid().ToString() );</pre>
            <pre style="MARGIN: 0px"> </pre>
            <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">try</span></pre>
            <pre style="MARGIN: 0px">    {</pre>
            <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">using</span>(
      AutoBatchUpdate auto = <span style="COLOR: #0000ff">new</span> AutoBatchUpdate( zip
      ) )</pre>
            <pre style="MARGIN: 0px">      {</pre>
            <pre style="MARGIN: 0px">        DiskFolder source = <span style="COLOR: #0000ff">new</span> DiskFolder(
      @"d:\Data" );</pre>
            <pre style="MARGIN: 0px">        source.CopyTo( zip, <span style="COLOR: #0000ff">true</span> );</pre>
            <pre style="MARGIN: 0px">      }</pre>
            <pre style="MARGIN: 0px">    }</pre>
            <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">finally</span></pre>
            <pre style="MARGIN: 0px">    {</pre>
            <pre style="MARGIN: 0px">      zip.TempFolder.Delete();</pre>
            <pre style="MARGIN: 0px">    }</pre>
          </div>
          <!--EndFragment-->
        </pre>
        <!--EndFragment-->
        <p>
      This makes sure no temp file survive a zipping cycle. And with that pattern, I can
      set the "default" temporary location once using the static DefaultTempFolder property,
      and each instance will use a unique folder within this starting point.
   </p>
        <p dir="ltr">
      Now that my zipping operations are cleaning their traces, we're ready to talk about
      aborting. Some key concepts:
   </p>
        <ul dir="ltr">
          <li>
            <div>The library isn't pumping messages, and does not offer async operations. If you
            want your WinForms application's "Abort" button to react, you will have to pump messages
            yourself somewhere.
         </div>
          </li>
          <li>
            <div>There are three major operations behind the creation or modification of
            a zip file:
         </div>
          </li>
          <ul>
            <li>
              <div>Compressing each new file.
            </div>
            </li>
            <li>
              <div>Moving each file to keep from the original zip file (if updating an existing
               zip file).
            </div>
            </li>
            <li>
              <div>Building the target zip file by appending data created by the above two steps.
            </div>
            </li>
          </ul>
          <li>
            <div>Zip and FileSystem events get raised at many levels, so you should pass your
            ZipEvents instance everywhere an overload accepting a FileSystemEvents or ZipEvents
            instance exists.
         </div>
          </li>
        </ul>
        <p>
      Your "Abort" button (or any abort input you like) will simply raise a flag. It can't
      do more.
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">private</span><span style="COLOR: #0000ff">bool</span> m_abort
      = <span style="COLOR: #0000ff">false</span>;</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">private</span><span style="COLOR: #0000ff">void</span> AbortButton_Click(<span style="COLOR: #0000ff">object</span> sender,
      System.EventArgs e)</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      m_abort = <span style="COLOR: #0000ff">true</span>;</pre>
          <pre style="MARGIN: 0px">    }</pre>
        </div>
        <!--EndFragment-->
        <!--EndFragment-->
        <!--EndFragment-->
        <p>
      Then you handle three events matching the forementioned three steps, pump messages
      to keep a responsive application, and check if the flag is raised. You can safely
      use the same method for handling the three events.
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">private</span><span style="COLOR: #0000ff">void</span> CheckAbort_ByteProgression(<span style="COLOR: #0000ff">object</span> sender,
      ByteProgressionEventArgs e)</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">if</span>(
      m_abort )</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">throw</span><span style="COLOR: #0000ff">new</span> ApplicationException(
      "The user aborted the operation." );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      Application.DoEvents();</pre>
          <pre style="MARGIN: 0px">    }</pre>
        </div>
        <!--EndFragment-->
        <p>
      As you can see, if the flag is raised, I'm throwing an ApplicationException. This
      will result in a System.Reflection.TargetInvocationException being thrown by the originally
      called method. To get a well-behaved application, you obviously want to trap any exception
      the FileSystem could throw. You can catch any TargetInvocationException to display
      an "operation aborted" message. Here's my code for the full operation:
   </p>
        <div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ">
          <pre style="MARGIN: 0px">    <span style="COLOR: #0000ff">private</span><span style="COLOR: #0000ff">void</span> StartButton_Click(<span style="COLOR: #0000ff">object</span> sender,
      System.EventArgs e)</pre>
          <pre style="MARGIN: 0px">    {</pre>
          <pre style="MARGIN: 0px">      m_abort = <span style="COLOR: #0000ff">false</span>;</pre>
          <pre style="MARGIN: 0px">      StartButton.Enabled = <span style="COLOR: #0000ff">false</span>;</pre>
          <pre style="MARGIN: 0px">      AbortButton.Enabled = <span style="COLOR: #0000ff">true</span>;</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">try</span></pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        ZipEvents events = <span style="COLOR: #0000ff">new</span> ZipEvents();</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      Advise for the three main events for checking abort flag.</span></pre>
          <pre style="MARGIN: 0px">        events.ByteProgression += </pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">new</span> ByteProgressionEventHandler(
      CheckAbort_ByteProgression );</pre>
          <pre style="MARGIN: 0px">        events.GatheringZipContentByteProgression += </pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">new</span> GatheringZipContentByteProgressionEventHandler(
      CheckAbort_ByteProgression );</pre>
          <pre style="MARGIN: 0px">        events.BuildingZipByteProgression += </pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">new</span> BuildingZipByteProgressionEventHandler(
      CheckAbort_ByteProgression );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      What's cool with delegates is that you can separate logic from UI.</span></pre>
          <pre style="MARGIN: 0px">        events.ByteProgression += </pre>
          <pre style="MARGIN: 0px">
            <span style="COLOR: #0000ff">new</span> ByteProgressionEventHandler(
      UpdateUI_ByteProgression );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        ZipArchive zip = <span style="COLOR: #0000ff">new</span> ZipArchive( </pre>
          <pre style="MARGIN: 0px">          events, <span style="COLOR: #0000ff">null</span>, <span style="COLOR: #0000ff">new</span> DiskFile(
      @"d:\temp\backup.zip" ) );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        zip.TempFolder = zip.TempFolder.CreateFolder( Guid.NewGuid().ToString() );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">try</span></pre>
          <pre style="MARGIN: 0px">        {</pre>
          <pre style="MARGIN: 0px">          <span style="COLOR: #0000ff">using</span>(
      AutoBatchUpdate auto = <span style="COLOR: #0000ff">new</span> AutoBatchUpdate( zip,
      events, <span style="COLOR: #0000ff">null</span> ) )</pre>
          <pre style="MARGIN: 0px">          {</pre>
          <pre style="MARGIN: 0px">            DiskFolder source = <span style="COLOR: #0000ff">new</span> DiskFolder(
      @"d:\Data" );</pre>
          <pre style="MARGIN: 0px">            source.CopyTo( events, <span style="COLOR: #0000ff">null</span>,
      zip, <span style="COLOR: #0000ff">true</span> );</pre>
          <pre style="MARGIN: 0px">          }</pre>
          <pre style="MARGIN: 0px">        }</pre>
          <pre style="MARGIN: 0px">        <span style="COLOR: #0000ff">finally</span></pre>
          <pre style="MARGIN: 0px">        {</pre>
          <pre style="MARGIN: 0px">          zip.TempFolder.Delete();</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">          <span style="BACKGROUND: #ffffff; COLOR: #008000">//
      Clean up events.</span></pre>
          <pre style="MARGIN: 0px">          events.ByteProgression -= </pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">new</span> ByteProgressionEventHandler(
      CheckAbort_ByteProgression );</pre>
          <pre style="MARGIN: 0px">          events.GatheringZipContentByteProgression -= </pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">new</span> GatheringZipContentByteProgressionEventHandler(
      CheckAbort_ByteProgression );</pre>
          <pre style="MARGIN: 0px">          events.BuildingZipByteProgression -= </pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">new</span> BuildingZipByteProgressionEventHandler(
      CheckAbort_ByteProgression );</pre>
          <pre style="MARGIN: 0px"> </pre>
          <pre style="MARGIN: 0px">          events.ByteProgression -= </pre>
          <pre style="MARGIN: 0px">            <span style="COLOR: #0000ff">new</span> ByteProgressionEventHandler(
      UpdateUI_ByteProgression );</pre>
          <pre style="MARGIN: 0px">        }</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">catch</span>(
      System.Reflection.TargetInvocationException except )</pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        MessageBox.Show( except.InnerException.Message, "Abort" );</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">catch</span>(
      Exception except )</pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        MessageBox.Show( except.Message, "Error" );</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px">      <span style="COLOR: #0000ff">finally</span></pre>
          <pre style="MARGIN: 0px">      {</pre>
          <pre style="MARGIN: 0px">        AbortButton.Enabled = <span style="COLOR: #0000ff">false</span>;</pre>
          <pre style="MARGIN: 0px">        StartButton.Enabled = <span style="COLOR: #0000ff">true</span>;</pre>
          <pre style="MARGIN: 0px">        m_abort = <span style="COLOR: #0000ff">false</span>;</pre>
          <pre style="MARGIN: 0px">      }</pre>
          <pre style="MARGIN: 0px">    }</pre>
        </div>
        <p>
      Things to notice:
   </p>
        <ul>
          <li>
         I'm passing my "events" instance to:</li>
          <ul>
            <li>
            The ZipArchive's ctor. You could handle the ReadingZipItemProgression events.</li>
            <li>
            The AutoBatchUpdate ctor, which will in turn pass it to both BeginUpdate and EndUpdate.
            The later method will generate the GatheringZipContentByteProgression and BuildingZipByteProgression
            events.</li>
            <li>
            The CopyTo method. It will generate the ByteProgression events.</li>
          </ul>
          <li>
         I'm advising two times for the ByteProgression events, once for handling abort conditions,
         and another for updating my UI. This is a cool way to leverage delegates and separate
         the logic from the UI.<!--EndFragment--></li>
        </ul>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=cff8fc14-76a1-4fde-a4f0-a49ab582a21a" />
      </body>
      <title>Aborting a zip operation</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,cff8fc14-76a1-4fde-a4f0-a49ab582a21a.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,cff8fc14-76a1-4fde-a4f0-a49ab582a21a.aspx</link>
      <pubDate>Thu, 19 May 2005 20:53:12 GMT</pubDate>
      <description>&lt;p&gt;
   Lately, people have been asking us how to abort a zipping operation with Xceed Zip
   for .NET. The official answer is "you can't", as there is no method or property exposed
   for this task, as opposed to Xceed Zip ActiveX with its simple Abort property. But
   the truth is you can, with relatively little coding.
&lt;/p&gt;
&lt;p&gt;
   Before we get into how to abort, let's talk a little bit about the ZipArchive's TempFolder
   property. By default, it points to the same folder as the static ZipArchive.DefaultTempFolder
   property, which itself points to the user's temp folder, as exposed by System.IO.Path.GetTempPath().
&lt;/p&gt;
&lt;p&gt;
   Though the library is designed to delete any file it creates in the temporary folder,
   this can occur only when instances get finalized if the operation failed in the middle
   of the process.
&lt;/p&gt;
&lt;p&gt;
   A good coding pattern I like to use is the following:
&lt;/p&gt;
&lt;pre style="MARGIN: 0px"&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; ZipArchive zip = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ZipArchive( &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; DiskFile(
   @"d:\temp\backup.zip" ) );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; zip.TempFolder = zip.TempFolder.CreateFolder( Guid.NewGuid().ToString() );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;try&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   AutoBatchUpdate auto = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; AutoBatchUpdate( zip
   ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DiskFolder source = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; DiskFolder(
   @"d:\Data" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; source.CopyTo( zip, &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt; );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;finally&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; zip.TempFolder.Delete();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;&lt;/pre&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   This makes sure no temp file survive a zipping cycle. And with that pattern, I can
   set the "default" temporary location once using the static DefaultTempFolder property,
   and each instance will use a unique folder within this starting point.
&lt;/p&gt;
&lt;p dir=ltr&gt;
   Now that my zipping operations are cleaning their traces, we're ready to talk about
   aborting. Some key concepts:
&lt;/p&gt;
&lt;ul dir=ltr&gt;
   &lt;li&gt;
      &lt;div&gt;The library isn't pumping messages, and does not offer async operations. If you
         want your WinForms application's "Abort" button to react, you will have to pump messages
         yourself somewhere.
      &lt;/div&gt;
   &lt;/li&gt;
   &lt;li&gt;
      &lt;div&gt;There are three major operations behind&amp;nbsp;the creation or modification of
         a zip file:
      &lt;/div&gt;
   &lt;/li&gt;
   &lt;ul&gt;
      &lt;li&gt;
         &lt;div&gt;Compressing each new file.
         &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
         &lt;div&gt;Moving each file to keep from the original zip file (if updating an existing
            zip file).
         &lt;/div&gt;
      &lt;/li&gt;
      &lt;li&gt;
         &lt;div&gt;Building the target zip file by appending data created by the above two steps.
         &lt;/div&gt;
      &lt;/li&gt;
   &lt;/ul&gt;
   &lt;li&gt;
      &lt;div&gt;Zip and FileSystem events get raised at many levels, so you should pass your
         ZipEvents instance everywhere an overload accepting a FileSystemEvents or ZipEvents
         instance exists.
      &lt;/div&gt;
   &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
   Your "Abort" button (or any abort input you like) will simply raise a flag. It can't
   do more.
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;bool&lt;/span&gt; m_abort
   = &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; AbortButton_Click(&lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt; sender,
   System.EventArgs e)&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; m_abort = &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;!--EndFragment--&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   Then you handle three events matching the&amp;nbsp;forementioned three steps, pump messages
   to keep a responsive application, and check if the flag is raised. You can safely
   use the same method for handling the three events.
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; CheckAbort_ByteProgression(&lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt; sender,
   ByteProgressionEventArgs e)&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(
   m_abort )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;throw&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ApplicationException(
   "The user aborted the operation." );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Application.DoEvents();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
   As you can see, if the flag is raised, I'm throwing an ApplicationException. This
   will result in a System.Reflection.TargetInvocationException being thrown by the originally
   called method. To get a well-behaved application, you obviously want to trap any exception
   the FileSystem could throw. You can catch any TargetInvocationException to display
   an "operation aborted" message. Here's my code for the full operation:
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 0pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 0pt; FONT-SIZE: 8pt; BACKGROUND: #ffffff; PADDING-BOTTOM: 0pt; BORDER-LEFT: windowtext 1pt solid; COLOR: #000000; PADDING-TOP: 0pt; BORDER-BOTTOM: windowtext 1pt solid; FONT-FAMILY: ProggySquareTTSZ"&gt;&lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; StartButton_Click(&lt;span style="COLOR: #0000ff"&gt;object&lt;/span&gt; sender,
   System.EventArgs e)&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; m_abort = &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; StartButton.Enabled = &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; AbortButton.Enabled = &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;try&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ZipEvents events = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ZipEvents();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   Advise for the three main events for checking abort flag.&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.ByteProgression += &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ByteProgressionEventHandler(
   CheckAbort_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.GatheringZipContentByteProgression += &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; GatheringZipContentByteProgressionEventHandler(
   CheckAbort_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.BuildingZipByteProgression += &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; BuildingZipByteProgressionEventHandler(
   CheckAbort_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   What's cool with delegates is that you can separate logic from UI.&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.ByteProgression += &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;          &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ByteProgressionEventHandler(
   UpdateUI_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ZipArchive zip = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ZipArchive( &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;          events, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; DiskFile(
   @"d:\temp\backup.zip" ) );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; zip.TempFolder = zip.TempFolder.CreateFolder( Guid.NewGuid().ToString() );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;try&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;using&lt;/span&gt;(
   AutoBatchUpdate auto = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; AutoBatchUpdate( zip,
   events, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt; ) )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; DiskFolder source = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; DiskFolder(
   @"d:\Data" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; source.CopyTo( events, &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;,
   zip, &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt; );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;finally&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; zip.TempFolder.Delete();&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="BACKGROUND: #ffffff; COLOR: #008000"&gt;//
   Clean up events.&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.ByteProgression -= &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ByteProgressionEventHandler(
   CheckAbort_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.GatheringZipContentByteProgression -= &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; GatheringZipContentByteProgressionEventHandler(
   CheckAbort_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.BuildingZipByteProgression -= &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; BuildingZipByteProgressionEventHandler(
   CheckAbort_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; events.ByteProgression -= &lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; ByteProgressionEventHandler(
   UpdateUI_ByteProgression );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;catch&lt;/span&gt;(
   System.Reflection.TargetInvocationException except )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MessageBox.Show( except.InnerException.Message, "Abort" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;catch&lt;/span&gt;(
   Exception except )&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; MessageBox.Show( except.Message, "Error" );&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0000ff"&gt;finally&lt;/span&gt;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AbortButton.Enabled = &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; StartButton.Enabled = &lt;span style="COLOR: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; m_abort = &lt;span style="COLOR: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
   &lt;pre style="MARGIN: 0px"&gt;&amp;nbsp; &amp;nbsp; }&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
   Things to notice:
&lt;/p&gt;
&lt;ul&gt;
   &lt;li&gt;
      I'm passing my "events" instance to:&lt;/li&gt;
   &lt;ul&gt;
      &lt;li&gt;
         The ZipArchive's ctor. You could handle the ReadingZipItemProgression events.&lt;/li&gt;
      &lt;li&gt;
         The AutoBatchUpdate ctor, which will in turn pass it to both BeginUpdate and EndUpdate.
         The later method will generate the GatheringZipContentByteProgression and BuildingZipByteProgression
         events.&lt;/li&gt;
      &lt;li&gt;
         The CopyTo method. It will generate the ByteProgression events.&lt;/li&gt;
   &lt;/ul&gt;
   &lt;li&gt;
      I'm advising two times for the ByteProgression events, once for handling abort conditions,
      and another for updating my UI. This is a cool way to leverage delegates and separate
      the logic from the UI.&lt;!--EndFragment--&gt;
   &lt;/li&gt;
&lt;/ul&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=cff8fc14-76a1-4fde-a4f0-a49ab582a21a" /&gt;</description>
      <category>.NET;Zip</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=7cf73d65-6780-4b51-a525-483ca0753c75</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,7cf73d65-6780-4b51-a525-483ca0753c75.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://blogs.msdn.com/danielfe/archive/2005/04/21/410463.aspx">You already
      know</a> the original picture shown on <a href="http://msdn.microsoft.com/coding4fun/">Coding4Fun</a> raised
      within me <a href="http://blogs.xceedsoft.com/plantem/PermaLink.aspx?guid=2339b234-dfd6-48df-854c-6901e2643648">some
      concerns</a> I was already outdated, old, unplugged, not into "it" anymore.
   </p>
        <p>
      Well, I'm thinking of launching a new portal called <strong>Coding4Work</strong>,
      where developers will feel more connected to the real thing. Instead of being welcomed
      by the "Tattoo Dude":
   </p>
        <p>
          <img height="169" alt="edited-poster-tattoodude.jpg" src="http://blogs.xceedsoft.com/plantem/content/binary/edited-poster-tattoodude.jpg" width="563" border="0" />
        </p>
        <p>
      You will be welcomed by the "Busy Dude":
   </p>
        <p>
          <img height="169" alt="martin-tattoodude.jpg" src="http://blogs.xceedsoft.com/plantem/content/binary/martin-tattoodude.jpg" width="563" border="0" />
        </p>
        <p>
      Hmmm, that's much closer to my life, dude! ;-)
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=7cf73d65-6780-4b51-a525-483ca0753c75" />
      </body>
      <title>Coding4Work - My new portal</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,7cf73d65-6780-4b51-a525-483ca0753c75.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,7cf73d65-6780-4b51-a525-483ca0753c75.aspx</link>
      <pubDate>Fri, 22 Apr 2005 19:48:17 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;a href="http://blogs.msdn.com/danielfe/archive/2005/04/21/410463.aspx"&gt;You already
   know&lt;/a&gt; the original picture shown on &lt;a href="http://msdn.microsoft.com/coding4fun/"&gt;Coding4Fun&lt;/a&gt; raised
   within me &lt;a href="http://blogs.xceedsoft.com/plantem/PermaLink.aspx?guid=2339b234-dfd6-48df-854c-6901e2643648"&gt;some
   concerns&lt;/a&gt; I was already outdated, old, unplugged, not into "it" anymore.
&lt;/p&gt;
&lt;p&gt;
   Well, I'm thinking of launching a new portal called &lt;strong&gt;Coding4Work&lt;/strong&gt;,
   where developers will feel more connected to the real thing. Instead of being welcomed
   by the "Tattoo Dude":
&lt;/p&gt;
&lt;p&gt;
   &lt;img height=169 alt=edited-poster-tattoodude.jpg src="http://blogs.xceedsoft.com/plantem/content/binary/edited-poster-tattoodude.jpg" width=563 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
   You will be welcomed by the "Busy Dude":
&lt;/p&gt;
&lt;p&gt;
   &lt;img height=169 alt=martin-tattoodude.jpg src="http://blogs.xceedsoft.com/plantem/content/binary/martin-tattoodude.jpg" width=563 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
   Hmmm, that's much closer to my life, dude! ;-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=7cf73d65-6780-4b51-a525-483ca0753c75" /&gt;</description>
      <category>.NET;Fun</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=2339b234-dfd6-48df-854c-6901e2643648</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,2339b234-dfd6-48df-854c-6901e2643648.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <a href="http://www.hanselman.com/blog/Coding4FunIsLIVEANewSyndicatedMSDNColumn.aspx">Scott
      is inviting</a> us on the MSDN <a href="http://msdn.microsoft.com/coding4fun/">Coding4Fun</a> portal,
      with news and articles on many programming topics.
   </p>
        <p>
      It's funny... or should I say perturbing... I'm welcomed by a young tattooed man wearing
      earphones, working on his laptop, peacefully in what appears to be his living room.
      The JPG filename is self-explanatory: "c4f-poster-tattoodude.jpg".
   </p>
        <p>
      I don't have tattoos. I don't have a laptop, I wouldn't code on one if I could anyway.
      I'm not a "dude" anymore, if I ever was one. I listen to music while coding only to
      isolate myself of the ambient office noise. I'm a happily maried father who's day
      job is to develop software, and used to have time to "Code 4 Fun" in a distant era.
   </p>
        <p>
      I'll be honest, I don't code for fun anymore. I'm having fun most of the time when
      I code, but I do it for work. I feel old and unplugged when I see "Dude" sites that
      tell me "programming is cool, man!".
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=2339b234-dfd6-48df-854c-6901e2643648" />
      </body>
      <title>Coding4Fun MSDN Portal</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,2339b234-dfd6-48df-854c-6901e2643648.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,2339b234-dfd6-48df-854c-6901e2643648.aspx</link>
      <pubDate>Mon, 18 Apr 2005 14:00:35 GMT</pubDate>
      <description>&lt;p&gt;
   &lt;a href="http://www.hanselman.com/blog/Coding4FunIsLIVEANewSyndicatedMSDNColumn.aspx"&gt;Scott
   is inviting&lt;/a&gt; us on the MSDN &lt;a href="http://msdn.microsoft.com/coding4fun/"&gt;Coding4Fun&lt;/a&gt; portal,
   with news and articles on many programming topics.
&lt;/p&gt;
&lt;p&gt;
   It's funny... or should I say perturbing... I'm welcomed by a young tattooed man wearing
   earphones, working on his laptop, peacefully in what appears to be his living room.
   The JPG filename is self-explanatory: "c4f-poster-tattoodude.jpg".
&lt;/p&gt;
&lt;p&gt;
   I don't have tattoos. I don't have a laptop, I wouldn't code on one if I could anyway.
   I'm not a "dude" anymore, if I ever was one. I listen to music while coding only to
   isolate myself of the ambient office noise. I'm a happily maried father who's day
   job is to develop software, and used to have time to "Code 4 Fun" in a distant era.
&lt;/p&gt;
&lt;p&gt;
   I'll be honest, I don't code for fun anymore. I'm having fun most of the time when
   I code, but I do it for work. I feel old and unplugged when I see "Dude" sites that
   tell me "programming is cool, man!".
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=2339b234-dfd6-48df-854c-6901e2643648" /&gt;</description>
      <category>.NET;Fun</category>
    </item>
    <item>
      <trackback:ping>http://blogs.xceedsoft.com/plantem/Trackback.aspx?guid=57f64980-5ba1-45d9-8da6-4c07050866f5</trackback:ping>
      <pingback:server>http://blogs.xceedsoft.com/plantem/pingback.aspx</pingback:server>
      <pingback:target>http://blogs.xceedsoft.com/plantem/PermaLink,guid,57f64980-5ba1-45d9-8da6-4c07050866f5.aspx</pingback:target>
      <dc:creator />
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
      The <a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=033204c1-38ad-4fce-b5ab-0e2ec2dff565&amp;DisplayLang=en">.NET
      Compact Framework 2.0 beta 2</a> is out! But it won't run on my awesome state-of-the-art
      Jornada 545. :-(
   </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <em>Supported Device Operating Systems: Windows Mobile Software for Pocket PC 2003
      Pocket PC, Microsoft® Windows Mobile™ version 5.0 for Pocket PC and Smartphone, and
      Windows CE .NET 5.0.</em>
          </p>
        </blockquote>
        <p dir="ltr">
      Ok, ok, I admit, I expected this! :-) My old Jornada is running Pocket PC 2000 (Windows
      CE 3.0 based), and has an astonishing 16 Mb of base storage to split with both storage
      and memory. Though I've installed the minimum in main storage, I have 7.5 Mb to work
      with when I boot. For example, I often can't open Windows Media Player and Word simulteneously,
      else I run out of memory.
   </p>
        <p dir="ltr">
      Don't get me wrong, I love my PDA... But less than a few years ago. The battery is
      giving me less up-time than before, and more often than before I can't find software
      to run on Pocket PC 2000. I expected this to happen one day. My biggest frustration
      is I can't install a new OS. Can't brun the ROM. It will die with Pocket PC 2000.
   </p>
        <p dir="ltr">
      But I'm a little surprise the new version of the .NET Compact Framework won't support
      Pocket PC 2002. Imagine if the regular .NET Framework was to only work on XP and 2003,
      but not on Windows 2000. People would scream! I thought the Windows CE 4.x market
      was big enough to justify supporting it. Oh well, I was wrong...
   </p>
        <p dir="ltr">
      BTW, do you know where and when I bought my Jornada? At the Microsoft Store during
      my first Early Adopters .NET lab at <a href="http://maps.google.com/maps?q=1+microsoft+way,redmond&amp;ll=47.643778,-122.131072&amp;spn=0.006158,0.007660&amp;t=k&amp;hl=en">Building
      20</a>. An impulsive decision at a time I didn't know I needed a PDA.
   </p>
        <img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=57f64980-5ba1-45d9-8da6-4c07050866f5" />
      </body>
      <title>.NET Compact Framework 2.0 beta 2 is out, but...</title>
      <guid>http://blogs.xceedsoft.com/plantem/PermaLink,guid,57f64980-5ba1-45d9-8da6-4c07050866f5.aspx</guid>
      <link>http://blogs.xceedsoft.com/plantem/PermaLink,guid,57f64980-5ba1-45d9-8da6-4c07050866f5.aspx</link>
      <pubDate>Mon, 18 Apr 2005 13:25:31 GMT</pubDate>
      <description>&lt;p&gt;
   The &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=033204c1-38ad-4fce-b5ab-0e2ec2dff565&amp;amp;DisplayLang=en"&gt;.NET
   Compact Framework 2.0 beta 2&lt;/a&gt; is out! But it won't run on my awesome state-of-the-art
   Jornada 545. :-(
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
   &lt;em&gt;Supported Device Operating Systems: Windows Mobile Software for Pocket PC 2003
   Pocket PC, Microsoft® Windows Mobile™ version 5.0 for Pocket PC and Smartphone, and
   Windows CE .NET 5.0.&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
   Ok, ok, I admit, I expected this! :-) My old Jornada is running Pocket PC 2000 (Windows
   CE 3.0 based), and has an astonishing 16 Mb of base storage to split with both storage
   and memory. Though I've installed the minimum in main storage, I have 7.5 Mb to work
   with when I boot. For example, I often can't open Windows Media Player and Word simulteneously,
   else I run out of memory.
&lt;/p&gt;
&lt;p dir=ltr&gt;
   Don't get me wrong, I love my PDA... But less than a few years ago. The battery is
   giving me less up-time than before, and more often than before I can't find software
   to run on Pocket PC 2000. I expected this to happen one day. My biggest frustration
   is I can't install a new OS. Can't brun the ROM. It will die with Pocket PC 2000.
&lt;/p&gt;
&lt;p dir=ltr&gt;
   But I'm a little surprise the new version of the .NET Compact Framework won't support
   Pocket PC 2002. Imagine if the regular .NET Framework was to only work on XP and 2003,
   but not on Windows 2000. People would scream! I thought the Windows CE 4.x market
   was big enough to justify supporting it. Oh well, I was wrong...
&lt;/p&gt;
&lt;p dir=ltr&gt;
   BTW, do you know where and when I bought my Jornada? At the Microsoft Store during
   my first Early Adopters .NET lab at &lt;a href="http://maps.google.com/maps?q=1+microsoft+way,redmond&amp;amp;ll=47.643778,-122.131072&amp;amp;spn=0.006158,0.007660&amp;amp;t=k&amp;amp;hl=en"&gt;Building
   20&lt;/a&gt;. An impulsive decision at a time I didn't know I needed a PDA.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blogs.xceedsoft.com/plantem/aggbug.ashx?id=57f64980-5ba1-45d9-8da6-4c07050866f5" /&gt;</description>
      <category>.NET</category>
    </item>
  </channel>
</rss>