Compressing a File as it is Uploaded
This summer I got to work on a project that stretched my experience a little by requiring that I learn to use the compression classes in the .NET framework. There is not a whole lot of stuff out there on using these classes so I thought I would attempt to show how to do something with them using the FileUpload control to put them in perspective.
The .NET compression classes are located in the System.IO.Compression namespace. A good introductory article on the .NET compression classes can be found on the MSDN Interop Blog.
The first thing I learned with the compression classes is that you need to either write you own wrapper classes around them or use something already out there. Fortunately Iconics has provided us some useful classes to help, you can download them from ICSharpCode.net. These are the classes I am using in this simple demonstration, but the day I put this demo together I noticed a new project on CodePlex.com for a managed Zip library.
I found myself recently uploading some files to a site and thought it might be worth my time to investigate what it would take to not only upload the file, but also compress it to save space. Which after my experience this summer turned out to be pretty easy.
The first thing to do is create a Web page with a FileUpload control and a submit button. Create a Click event handler for the Submit button and add some code to manage our upload and compression.
The Iconics classes come in a C# library, which you can reference from any ASP.NET web site. You can either make the iconics namespaces global or import them (yes using for you C# guys) at the page level, which is what I do in this example. You will also want to import a reference to the System.IO namespace as well.
Imports
ionicImports
ionic.utilsImports
ionic.utils.zipImports
System.ioFor the sake of a sort demo I code a file name and use the ApplicationPath property.
Private
sZipFileAs
String
='MyZipFile.zip'
Private
sAppPathAs
String
= HttpContext.Current.Request.PhysicalApplicationPathI also created a couple of helper methods to return the proper file names for the uploaded file and the zip file.
Private
Function
GetUploadedFileName()As
String
Return
Path.Combine(sAppPath, FileUpload1.FileName)
End
Function
Private
Function
GetZipFileName()As
String
Return
Path.Combine(sAppPath,'MyZipFile.zip'
)
End
Function
In the Button Click event handler the first thing to do is check an see if there is a file being uploaded. If yes, then proceed to store it in a zipped file. For this demo I am going to keep things simple and store my uploaded file on the hard drive first, then compress it and finally delete the file. To be on the safe side I check to see if I have a file and a zip library by the same names and if so I delete them.
Next I save the File from the FileUpload control to the hard drive. Then I create a new Zip library based on the name of the zip file I want. In order for the zip file to work with the built in compression functionality in Windows we need to trim the leading drive letter, so I set TrimVolumeFromFullyQualifiedPaths to true for this. Then you can add the file to your zip library and save the library. Finally clean things up and delete the uploaded file.
Protected
Sub
Button1_Click(ByVal
senderAs
Object
,ByVal
eAs
System.EventArgs)Handles
Button1.Click
'Check to see if we actually have a file to process.
If
FileUpload1.HasFileThen
'Delete the file if it already exists
If
File.Exists(GetUploadedFileName)Then
File.Delete(GetUploadedFileName)
End
If
'First check to see if the Zip file already exists or not.
'If it does we need to either throw an exception, let the user deal with it or just delete the existing file and get on with life...
If
File.Exists(GetZipFileName)Then
File.Delete(GetZipFileName)
End
If
'If we do, then save it locally. Note: your desitnation folder or path must have write permissions available to either the ASP.NET or Network Services account.
FileUpload1.SaveAs(GetUploadedFileName)
'Now Add the file to the Zip File.
Dim
zfAs
New
ZipFile(GetZipFileName)zf.TrimVolumeFromFullyQualifiedPaths =
True
zf.AddFile(GetUploadedFileName)
zf.Save()
Label1.Text =
String
.Format('Your file {0} has been uploaded and compressed to {1}'
, FileUpload1.FileName,'MyZipFile.zip'
)
HyperLink1.Visible =
True
HyperLink1.NavigateUrl =
'MyZipFile.zip'
File.Delete(GetUploadedFileName)
End
If
End
Sub
I have added a few feedback helpers in a label and a hyperlink that can be clicked to download the zip file. There are so many other things I think you could accomplish with this. I want to extend this somehow to directly use the FileStream from the FileUpload control for example. I also want to manage the code to be able to add to and update contents of an existing zip library. So stay tuned as I get some time slices for that.