/Source Code/FileArchive/ArchiveFile.vb
Visual Basic | 119 lines | 63 code | 26 blank | 30 comment | 1 complexity | ddad055ede50eb50e99d3e1c94fbd637 MD5 | raw file
- Imports System.IO
-
- ''' <summary>
- ''' Represents a file in an archive.
- ''' </summary>
- Public Class ArchiveFile
-
- Private FFileName As String = String.Empty
- Private FFile As BinaryReader = Nothing
- Private FFileTable As FileTable = Nothing
-
- ''' <summary>
- ''' Do not allow construction of the <see cref="ArchiveFile" /> class.
- ''' </summary>
- ''' <param name="fileName">Name of the file.</param>
- Private Sub New(ByVal fileName As String)
- FFileName = fileName
- FFile = New BinaryReader(New FileStream(fileName, FileMode.Open))
- FFileTable = GetFileTable()
- End Sub
-
- ''' <summary>
- ''' Closes the open archive file.
- ''' </summary>
- Public Sub Close()
- FFile.Close()
- End Sub
-
- ''' <summary>
- ''' Creates a new archive file based on the specified file name and file table.
- ''' </summary>
- ''' <param name="fileName">Name of the file.</param>
- ''' <param name="fileTable">The file table that specifies what goes into the archive.</param>
- Public Shared Sub Create(ByVal fileName As String, ByVal fileTable As FileTable)
-
- Dim File As New BinaryWriter(New FileStream(fileName, FileMode.Create))
-
- ' Write file table
- WriteFileTable(File, fileTable)
-
- ' Write the files
- For FileIndex As Integer = 0 To fileTable.FileCount - 1
- Dim TableEntry As EntryData = fileTable.Files(FileIndex)
- Dim InputFile As New BinaryReader(New FileStream(TableEntry.FileName, FileMode.Open))
- Dim FileLength As Integer = CInt(InputFile.BaseStream.Length)
- Dim Contents As Byte() = InputFile.ReadBytes(FileLength)
- fileTable.SetFilePosition(TableEntry.VirtualFileName, CInt(File.BaseStream.Position))
- File.Write(FileLength)
- File.Write(Contents)
- InputFile.Close()
- Next
-
- ' Write the amended file table and close the file
- WriteFileTable(File, fileTable)
- File.Close()
-
- End Sub
-
- ''' <summary>
- ''' Loads the specified file.
- ''' </summary>
- ''' <param name="fileName">Name of the file to load.</param>
- ''' <returns>The archive file at the given location.</returns>
- Public Shared Function Load(ByVal fileName As String) As ArchiveFile
- Return New ArchiveFile(fileName)
- End Function
-
- Public Function GetFile(ByVal virtualFileName As String) As Byte()
-
- FFile.BaseStream.Position = FFileTable.GetFilePosition(virtualFileName)
- Dim FileLength As Integer = FFile.ReadInt32
- Return FFile.ReadBytes(FileLength)
-
- End Function
-
- ''' <summary>
- ''' Gets all files in the archive.
- ''' </summary>
- ''' <returns>A list of all of the files in the archive.</returns>
- Public Function GetAllFiles() As String()
- Return FFileTable.VirtualFileNames
- End Function
-
- Private Function GetFileTable() As FileTable
-
- FFile.BaseStream.Position = 0
- Dim FileCount As Integer = FFile.ReadInt32
- Dim Result As New FileTable
- For FileIndex As Integer = 0 To FileCount - 1
-
- ' Get data about the file
- Dim VirtualFileName As String = FFile.ReadString
- Dim Position As Integer = FFile.ReadInt32
-
- ' Do some sanity checking
- If VirtualFileName.Trim.Length = 0 Then Throw New ApplicationException("Virtual file name has not been specified.")
- If Position = 0 Then Throw New ApplicationException("Invalid position for file '" + VirtualFileName + "' in archive.")
-
- ' Add the file to the list
- Result.AddFile(VirtualFileName, VirtualFileName, Position)
-
- Next
- Return Result
-
- End Function
-
- Private Shared Sub WriteFileTable(ByVal file As BinaryWriter, ByVal fileTable As FileTable)
-
- file.BaseStream.Position = 0
- file.Write(fileTable.FileCount)
- For FileIndex As Integer = 0 To fileTable.FileCount - 1
- Dim TableEntry As EntryData = fileTable.Files(FileIndex)
- file.Write(TableEntry.VirtualFileName)
- file.Write(TableEntry.Position)
- Next
-
- End Sub
-
- End Class