178 lines
7.2 KiB
VB.net
178 lines
7.2 KiB
VB.net
Imports Microsoft.VisualBasic
|
|
Imports System
|
|
Imports System.IO
|
|
Imports DevExpress.Xpo
|
|
Imports System.ComponentModel
|
|
Imports DevExpress.Persistent.Base
|
|
Imports DevExpress.Persistent.BaseImpl
|
|
Imports DevExpress.Persistent.Validation
|
|
|
|
'Dennis: the FileDataEx class allows you to store files in file system instead of the database. You can set the required path in the DefaultDirectory constant.
|
|
<Persistent(), DefaultProperty("FileName")> _
|
|
Public Class FileDataEx
|
|
Inherits BaseObject
|
|
Implements IFileData, IEmptyCheckable
|
|
Public Const DefaultDirectory As String = "D:\Store\"
|
|
Private Const ReadBytesSize As Integer = &H1000
|
|
Private tempStream As Stream = Nothing
|
|
Private tempFileName As String = String.Empty
|
|
|
|
<Persistent("Size")> _
|
|
Private _Size As Integer
|
|
<PersistentAlias("_Size")> _
|
|
Public ReadOnly Property Size() As Integer Implements IFileData.Size
|
|
Get
|
|
Return _Size
|
|
End Get
|
|
End Property
|
|
Public Sub New(ByVal session As Session)
|
|
MyBase.New(session)
|
|
End Sub
|
|
Public Overrides Function ToString() As String
|
|
Return FileName
|
|
End Function
|
|
Private _Content() As Byte
|
|
<Browsable(False), MemberDesignTimeVisibility(False), EditorBrowsable(EditorBrowsableState.Never)> _
|
|
Public Property Content() As Byte()
|
|
Get
|
|
Return _Content
|
|
End Get
|
|
Set(ByVal value As Byte())
|
|
SetPropertyValue("Content", _Content, value)
|
|
End Set
|
|
End Property
|
|
<NonPersistent(), MemberDesignTimeVisibility(False)> _
|
|
Public ReadOnly Property IsEmpty() As Boolean Implements IEmptyCheckable.IsEmpty
|
|
Get
|
|
Return String.IsNullOrEmpty(_FileName) AndAlso Not Exists
|
|
End Get
|
|
End Property
|
|
Public Overrides Sub AfterConstruction()
|
|
MyBase.AfterConstruction()
|
|
If (Not Directory.Exists(DefaultDirectory)) Then
|
|
Directory.CreateDirectory(DefaultDirectory)
|
|
End If
|
|
End Sub
|
|
Private _FileName As String = String.Empty
|
|
<Size(260)> _
|
|
Public Property FileName() As String Implements IFileData.FileName
|
|
Get
|
|
Return _FileName
|
|
End Get
|
|
Set(ByVal value As String)
|
|
SetPropertyValue("FileName", _FileName, value)
|
|
End Set
|
|
End Property
|
|
Public ReadOnly Property RealFileName() As String
|
|
Get
|
|
|
|
If _FileName <> String.Empty Then
|
|
Return Path.Combine(DefaultDirectory, GetUniqueFileName(_FileName))
|
|
Else
|
|
Return String.Empty
|
|
End If
|
|
End Get
|
|
End Property
|
|
Protected Overridable Function GetUniqueFileName(ByVal shortFileName As String) As String
|
|
Return String.Format("{0}-{1}", Oid, shortFileName)
|
|
End Function
|
|
Protected Overridable Function GetShortFileName(ByVal uniqueFileName As String) As String
|
|
Return uniqueFileName.Replace(String.Format("{0}-", Oid), String.Empty).Replace(DefaultDirectory, String.Empty)
|
|
End Function
|
|
Public ReadOnly Property Exists() As Boolean
|
|
Get
|
|
Return File.Exists(RealFileName)
|
|
End Get
|
|
End Property
|
|
'Dennis: fires when assigning a file.
|
|
Public Sub LoadFromStream(ByVal fileName As String, ByVal source As Stream) Implements IFileData.LoadFromStream
|
|
tempStream = source
|
|
'Dennis: when assigning a new file we need to save the name of the old file to remove it from the store in the future.
|
|
If String.IsNullOrEmpty(tempFileName) Then
|
|
tempFileName = RealFileName
|
|
End If
|
|
Me.FileName = fileName
|
|
End Sub
|
|
'Dennis: fires when saving or opening a file.
|
|
Public Sub SaveToStream(ByVal destination As Stream) Implements IFileData.SaveToStream
|
|
Try
|
|
Using source As Stream = File.OpenRead(RealFileName)
|
|
Dim buffer(ReadBytesSize - 1) As Byte
|
|
Dim read As Integer = 0
|
|
read = source.Read(buffer, 0, buffer.Length)
|
|
Do While read > 0
|
|
destination.Write(buffer, 0, read)
|
|
read = source.Read(buffer, 0, buffer.Length)
|
|
Loop
|
|
End Using
|
|
Catch exc As DirectoryNotFoundException
|
|
Throw New Exception(String.Format("Cannot access the '{0}' store because it is not available.", DefaultDirectory), exc)
|
|
Catch exc As FileNotFoundException
|
|
Throw New Exception(String.Format("Cannot access the '{0}' file because it is not found in the store.", FileName), exc)
|
|
End Try
|
|
End Sub
|
|
Protected Overrides Sub OnSaving()
|
|
MyBase.OnSaving()
|
|
If tempStream IsNot Nothing AndAlso (Not String.IsNullOrEmpty(RealFileName)) Then
|
|
Dim source As Stream = Nothing
|
|
'Dennis: for Windows Forms applications.
|
|
If TypeOf tempStream Is FileStream Then
|
|
Try
|
|
source = File.OpenRead((CType(tempStream, FileStream)).Name)
|
|
Catch exc As FileNotFoundException
|
|
Throw New Exception(String.Format("Cannot read the '{0}' file from a temporary store.", FileName), exc)
|
|
End Try
|
|
Else
|
|
'Dennis: for Web Forms applications.
|
|
source = tempStream
|
|
End If
|
|
Try
|
|
Using destination As Stream = File.OpenWrite(RealFileName)
|
|
Dim buffer(ReadBytesSize - 1) As Byte
|
|
Dim read As Integer = 0
|
|
read = source.Read(buffer, 0, buffer.Length)
|
|
Do While read > 0
|
|
destination.Write(buffer, 0, read)
|
|
read = source.Read(buffer, 0, buffer.Length)
|
|
Loop
|
|
UpdateSize(destination)
|
|
End Using
|
|
Catch exc As DirectoryNotFoundException
|
|
Throw New Exception(String.Format("Cannot access the '{0}' store because it is not available.", DefaultDirectory), exc)
|
|
Finally
|
|
source.Close()
|
|
source = Nothing
|
|
End Try
|
|
End If
|
|
'Dennis: removing the old file from the store when saving the current object.
|
|
If (Not String.IsNullOrEmpty(tempFileName)) Then
|
|
Try
|
|
File.Delete(tempFileName)
|
|
tempFileName = String.Empty
|
|
Catch exc As DirectoryNotFoundException
|
|
Throw New Exception(String.Format("Cannot access the '{0}' store because it is not available.", DefaultDirectory), exc)
|
|
End Try
|
|
End If
|
|
End Sub
|
|
Protected Overrides Sub OnDeleting()
|
|
'Dennis: first we need to remove the old file from the store.
|
|
Clear()
|
|
MyBase.OnDeleting()
|
|
End Sub
|
|
Private Sub UpdateSize(ByVal stream As Stream)
|
|
If stream Is Nothing Then
|
|
_Size = 0
|
|
Else
|
|
_Size = CInt(Fix(stream.Length))
|
|
End If
|
|
End Sub
|
|
Public Sub Clear() Implements IFileData.Clear
|
|
'Dennis: when clearing the file name property we need to save the name of the old file to remove it from the store in the future.
|
|
If String.IsNullOrEmpty(tempFileName) Then
|
|
tempFileName = RealFileName
|
|
End If
|
|
FileName = String.Empty
|
|
UpdateSize(Nothing)
|
|
End Sub
|
|
End Class
|