- Imports System.IO
- Imports System.Runtime.InteropServices
- Imports System.ComponentModel
- Public Class Form1
- Dim cfm As New CoalescentFileManager
- Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
- For Each x In My.Computer.FileSystem.GetFiles(My.Computer.FileSystem.SpecialDirectories.MyPictures, FileIO.SearchOption.SearchTopLevelOnly, ("*.jpg"))
- cfm.AddSourceFile(x)
- Console.WriteLine(x)
- Next
- '
- cfm.WriteCoalescentFile(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "/" & "xx.dat")
- cfm.LoadCoalescentFile(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "/" & "xx.dat")
- ListBox1.Items.AddRange(cfm.CurrentCoalescentFile.NameList)
- 'cfm.CurrentCoalescentFile.RevertCoalescentFileToDirectory(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "/xx/")
- End Sub
- Private Sub ListBox1_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged
- Me.BackgroundImage = Image.FromStream(cfm.CurrentCoalescentFile.GetStream(ListBox1.SelectedIndex))
- End Sub
- End Class
- Public Class CoalescentFileManager
- Dim _fullFilenameList As New List(Of String)
- Dim _coaFileLoaded As Boolean
- Dim _cf As CoalescentFile
- Sub New()
- End Sub
- Sub AddSourceFile(ByVal source As String)
- If Not File.Exists(source) Then Return
- _fullFilenameList.Add(source)
- End Sub
- Public Sub WriteCoalescentFile(ByVal filename As String)
- WriteCoalescentFile(filename, False)
- End Sub
- Public Sub WriteCoalescentFile(ByVal filename As String, ByVal useDeflate As Boolean)
- Using fs As New FileStream(filename, FileMode.Create, FileAccess.ReadWrite)
- Dim bw As New BinaryWriter(fs)
- '
- bw.Write("CoalescentFile")
- '
- bw.Write(useDeflate)
- '占用了4字节
- bw.Write(_fullFilenameList.Count)
- For Each f In _fullFilenameList
- Dim fi As New FileInfo(f)
- '每个占用8字节
- bw.Write(fi.Length)
- fi = Nothing
- Next
- For Each f In _fullFilenameList
- bw.Write(Path.GetFileName(f))
- Next
- For Each f In _fullFilenameList
- bw.Write(File.ReadAllBytes(f))
- bw.Flush()
- Next
- bw.Close()
- End Using
- End Sub
- Public Sub LoadCoalescentFile(ByVal coalescentFile As String)
- If Not File.Exists(coalescentFile) Then
- Throw New InvalidCoalescentFileException("所指示文件不存在。")
- End If
- Using fs As New FileStream(coalescentFile, FileMode.Open, FileAccess.Read)
- Dim br As New BinaryReader(fs)
- Dim headStr As String = br.ReadString
- If headStr <> "CoalescentFile" Then
- Throw New InvalidCoalescentFileException("该文件不是有效的合并文件。")
- End If
- End Using
- _cf = New CoalescentFile(coalescentFile)
- _coaFileLoaded = True
- End Sub
- Public ReadOnly Property CurrentCoalescentFile() As CoalescentFile
- Get
- Return _cf
- End Get
- End Property
- Public Class CoalescentFile
- Dim _shortNameList As List(Of String)
- Dim _fileLengthList As List(Of Long)
- Dim _fileCount As Integer
- Dim _isZip As Boolean
- Dim _cf As String
- Dim _contentStartPos As Long
- Sub New(ByVal cf As String)
- _shortNameList = New List(Of String)
- _fileLengthList = New List(Of Long)
- _cf = cf
- Using fs As New FileStream(_cf, FileMode.Open, FileAccess.Read)
- Dim br As New BinaryReader(fs)
- br.ReadString()
- _isZip = br.ReadBoolean
- _fileCount = br.ReadInt32
- For i = 1 To _fileCount
- _fileLengthList.Add(br.ReadInt64())
- Next
- For i = 1 To _fileCount
- _shortNameList.Add(br.ReadString)
- Next
- _contentStartPos = fs.Position
- br.Close()
- End Using
- End Sub
- Public Sub RevertCoalescentFileToDirectory(ByVal dir As String)
- If Not Directory.Exists(dir) Then Directory.CreateDirectory(dir)
- Using fs As New FileStream(_cf, FileMode.Open, FileAccess.Read)
- Dim br As New BinaryReader(fs)
- fs.Position = _contentStartPos
- For i = 0 To _fileCount - 1
- Dim buffer = br.ReadBytes(_fileLengthList(i))
- File.WriteAllBytes(dir & _shortNameList(i), buffer)
- Next
- br.Close()
- End Using
- End Sub
- Public Sub WriteOneToFile(ByVal index As Integer, ByVal file As String)
- Using fs As New FileStream(file, FileMode.Create, FileAccess.Write)
- Using mems As MemoryStream = GetStream(index)
- Dim bw As New BinaryWriter(fs)
- '若用 memoryStream.GetBuffer 方法则会在末尾多出一些 空符(字符码为零)
- bw.Write(mems.ToArray)
- bw.Close()
- End Using
- End Using
- End Sub
- Public Function GetStream(ByVal index As Integer) As MemoryStream
- Dim startPos As Long = _contentStartPos
- For i = 0 To index - 1
- startPos += _fileLengthList(i)
- Next
- Dim buffer As Byte()
- Using fs As New FileStream(_cf, FileMode.Open, FileAccess.Read)
- Dim br As New BinaryReader(fs)
- fs.Position = startPos
- buffer = br.ReadBytes(_fileLengthList(index))
- br.Close()
- End Using
- Dim mems As MemoryStream
- mems = New MemoryStream(buffer)
- Erase buffer
- GC.Collect()
- Return mems
- End Function
- Public ReadOnly Property NameList() As String()
- Get
- Return _shortNameList.ToArray
- End Get
- End Property
- Public ReadOnly Property FileCount() As Integer
- Get
- Return _fileCount
- End Get
- End Property
- Public ReadOnly Property CurrentFile() As String
- Get
- Return _cf
- End Get
- End Property
- Public ReadOnly Property IsDeflate() As Boolean
- Get
- Return _isZip
- End Get
- End Property
- End Class
- End Class
- Public Class InvalidCoalescentFileException
- Inherits Exception
- Sub New(ByVal text As String)
- MyBase.New(text)
- End Sub
- End Class