The FileInformation Helper Class
As you saw in the ZIPHandler section, FileInformation is a helper class which encapsulates the download state, e.g. in-progress, broken, etc. (see Listing 2
for the complete code).
To create an instance of FileInformation, you pass the class constructor the path to the requested file.
Public Sub New(ByVal sPath As String)
m_objFile = New System.IO.FileInfo(sPath)
FileInformation uses a System.IO.FileInfo object to get information about that file, which it exposes as properties, for example, whether the file exists, its full name, size, etc. The class also exposes a DownloadState
enumeration that describes the various states of a download request:
<Flags()> Enum DownloadState
' Clear: No download in progress,
' the file can be manipulated
fsClear = 1
' Locked: A dynamically created file must
' not be changed
fsLocked = 2
' In Progress: File is locked, and download
' is currently in progress
fsDownloadInProgress = 6
' Broken: File is locked, download was in
' progress, but was cancelled
fsDownloadBroken = 10
' Finished: File is locked, download
' was completed
fsDownloadFinished = 18
FileInformation also provides the EntityTag
property value. The sample code
has a hard-coded value in it, because the sample uses only one download file, which will not be changed, but for a real-world application, where you're serving multiple files, or even create files dynamically, your code must provide unique EntityTag
values for each file. Plus, each time that you change or edit the file that value must change as well. This enables client software to verify if the chunk they downloaded before is still up-to-date. Here's the section that returns the hard-coded EntityTag
value in the sample code.
Public ReadOnly Property EntityTag() As String
' The EntityTag used in the initial (200) response
' to, and in resume-Requests from clients
' ToDo - your code here
' (Create a unique string for your file)
' Please note, that this unique code must remain
' the same as long as the file does not change.
' If the file DOES change or is edited, however,
' the code MUST change.
A simple and probably safe enough EntityTag
could be a combination of the file name and the file's last modified date. Whatever method you choose, please make sure that it is truly unique and can't be confused with another file's EntityTag
. I prefer to name dynamically created files in my applications after the client, customer, and zip queue indexes, and use a GUID saved in a database for the EntityTag
The ZipFileHandler reads and sets the public State
property. After a completed download, it sets State
. At that point you can delete temporary files. Always call the Save
method here, to persist the state.
Public Property State() As DownloadState
Set(ByVal nState As DownloadState)
m_nState = nState
' ToDo - optional
' At this point, you could delete the
' file automatically.
' If the state is set to Finished, you
' might not need the file anymore:
' If nState = _
' DownloadState.fsDownloadFinished Then
' End If
The ZipFileHandler should call the Save
method whenever the file state changes, saving the file's state, so it can be displayed to the user at a later time. You can also use it to save the EntityTag
you created. Do not save the file's state and EntityTag
value to the Application, Session, or Cacheyou must persist that information across any of those lifecycles.
Private Sub Save()
' ToDo - your code here
' Save the state of this file's download
' to a database or XML file...)
' If you do not create files dynamically,
' you do not need to save the state, of course.
As written, the sample code
handles only one existing file (download.zip
); however you can enhance it to create requested files on demand.
When testing the sample code, your local system or LAN will probably be too fast to interrupt the download, so I recommend you use either a slow LAN connection (one way to simulate one is to reduce your site's bandwidth in IIS) or a live server on the Internet.
Downloading can still be tough on the client side. Broken or misconfigured Web cache servers operated by ISPs can ruin large downloads, inducing corruption or early session termination. If your files exceed 255 MB in size, you might want to encourage your customers to use third-party download manager software, although some newer browsers have basic download managers built-in.
If you want to extend the sample code even more, it's worth taking another look at the HTTP specifications. You could create MD5 digest values for the download, and add them using Content-MD5 header, providing a way to check the integrity of the download. The sample doesn't cover HTTP methods other than GET and HEAD, either.