📄 filestream.cls
字号:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
Persistable = 0 'NotPersistable
DataBindingBehavior = 0 'vbNone
DataSourceBehavior = 0 'vbNone
MTSTransactionMode = 0 'NotAnMTSObject
END
Attribute VB_Name = "FileStream"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = True
' CopyRight (c) 2004 Kelly Ethridge
'
' This file is part of VBCorLib.
'
' VBCorLib is free software; you can redistribute it and/or modify
' it under the terms of the GNU Library General Public License as published by
' the Free Software Foundation; either version 2.1 of the License, or
' (at your option) any later version.
'
' VBCorLib is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' GNU Library General Public License for more details.
'
' You should have received a copy of the GNU Library General Public License
' along with Foobar; if not, write to the Free Software
' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'
' Module: FileStream
'
''
' Represents a file as a Stream.
'
' @remarks A <b>FileStream</b> object cannot be created directly. In order to create a new
' <b>FileStream</b> object, use the <b>Cor.NewFileStream</b> method.
' <p>The FileStream can be used to create and modify files saved to disk. Through the stream
' the file can be navigated to specified byte positions within the file and the data can be read
' or written. Writing data will overwrite the data currently in the file at that location. As
' data is read or written, the file pointer is advanced the number of bytes read or written.</p>
' <p>Additionally, and existing handle to a file, pipe, or mailslot can have a stream created
' around it. These streams are not seekable, meaning the position within the stream cannot be
' set manually. Reading and writing to these streams still cause the pointer to advance the
' appropriate number of bytes.</p>
' <p>The FileStream object buffers reads and writes to the underlying stream for improved
' performance. It is assumed that several reads or several writes will occur repeatedly.
' This allows a single buffer to be used between reading and writing. If reading begins and
' there is data written, the data is flushed out to the stream to ensure the stream remains
' in sync. The buffer is then filled with <i>BufferSize</i> bytes for a quicker read.</p>
'
' @see Constructors
' @see Stream
' @include "..\..\Includes\FileStream.txt"
Option Explicit
Implements IObject
Implements Stream
Private Const FILE_ATTRIBUTE_NORMAL As Long = &H80
Private Const FILE_TYPE_DISK As Long = 1
Private Const MIN_BUFFERSIZE As Long = 8
Private Const CONSIDERED_MISSING As Long = -1
Private Const NO_ERROR As Long = 0
Private Const INVALID_SET_FILE_POINTER As Long = -1
Private Const INVALID_FILE_SIZE As Long = -1
Private Const ERROR_BROKEN_PIPE As Long = 109
Private Type OVERLAPPED
Internal As Long
InternalHigh As Long
Offset As Long
OffsetHigh As Long
hEvent As Long
End Type
''
' The modes in which to open a FileStream
'
' @param Append Opens an existing or creates a new file, then moves to the end
' for writing to begin at. Reading of the stream is not supported.
' @param Create Creates a new file. If the file already exists, it is overwritten.
' @param CreateNew Creates a new file. If the file already exists, then an IOException is thrown.
' @param OpenExisting Opens an existing file. If the file does not exist, then a FileNotFoundException is thrown.
' @param OpenOrCreate Opens an existing file. If the file does not exist, it will be created.
' @param Truncate Opens an existing file and sets the file length to 0. If an attempt to
' read is made, then an exception will be thrown.
'
Public Enum FileMode
Append = &H80
Create = 2
CreateNew = 1
OpenExisting = 3
OpenOrCreate = 4
Truncate = 5
End Enum
''
' The accesses allowed to the FileStream.
'
' @param ReadAccess Grants read permission to the FileStream.
' @param WriteAccess Grants write permission to the FileStream.
' @param ReadWriteAccess Grants both read and write permissions to the FileStream.
'
Public Enum FileAccess
ReadAccess = &H80000000
WriteAccess = &H40000000
ReadWriteAccess = &HC0000000
End Enum
''
' How the underlying stream can be shared with other processes.
'
' @param None The stream is not shared with other processes.
' @param ReadShare Other processes can access the file with read access only.
' @param WriteShare Other processes can access the file with write access only.
' @param ReadWriteShare Other processes can access the file with read and write access.
'
Public Enum FileShare
None = 0
ReadShare = 1
WriteShare = 2
ReadWriteShare = 3
End Enum
Private mName As String
Private mHandle As Handle
Private mCanRead As Boolean
Private mCanWrite As Boolean
Private mCanSeek As Boolean
Private mMinPosition As Currency
Private mOwnsHandle As Boolean
Private mIsOpen As Boolean
Private mFilePosition As Currency
Private mWritePosition As Long
Private mReadPosition As Long
Private mBuffer() As Byte
Private mBufferSize As Long
Private mBufferOffset As Currency
Private mBytesBuffered As Long
Private mIsAsync As Boolean
''
' Returns if this object can timeout.
'
' @return Always returns False for a FileStream.
'
Public Property Get CanTimeout() As Boolean
CanTimeout = False
End Property
''
' Returns the read timeout duration.
'
' @return The timeout duration.
' @remarks This is not supported in FileStream. An exception will be thrown.
'
Public Property Get ReadTimeout() As Long
Throw Cor.NewInvalidOperationException(Environment.GetResourceString(InvalidOperation_Timeouts))
End Property
''
' Sets the read timeout duration.
'
' @param RHS The timeout duration in milliseconds.
' @remarks This is not supported in FileStream. An exception will be thrown.
'
Public Property Let ReadTimeout(ByVal RHS As Long)
Throw Cor.NewInvalidOperationException(Environment.GetResourceString(InvalidOperation_Timeouts))
End Property
''
' Returns the write timeout duration.
'
' @return The write timeout duration.
' @remarks This is not supported in FileStream. An exception will be thrown.
'
Public Property Get WriteTimeout() As Long
Throw Cor.NewInvalidOperationException(Environment.GetResourceString(InvalidOperation_Timeouts))
End Property
''
' Sets the write timeout duration.
'
' @param RHS The timeout duration in milliseconds.
' @remarks This is not supported in FileStream. An exception will be thrown.
'
Public Property Let WriteTimeout(ByVal RHS As Long)
Throw Cor.NewInvalidOperationException(Environment.GetResourceString(InvalidOperation_Timeouts))
End Property
''
' Returns whether or not the FileStream was opened up in asynchronous mode.
'
' @return Boolean indicating if the FileStream is in asynchronous mode or not.
'
Public Property Get IsAsync() As Boolean
IsAsync = mIsAsync
End Property
''
' Returns the name of the underlying stream.
'
' @return If the stream is a file, then the file name is returned, otherwise the name is unknown.
'
Public Property Get Name() As String
If Len(Name) = 0 Then
Name = "Unknown Stream Name"
Else
Name = mName
End If
End Property
''
' Returns an indication for the ability to read from the file stream.
'
' @return An indication for being able to read from the file stream.
'
Public Property Get CanRead() As Boolean
CanRead = (mCanRead And mIsOpen)
End Property
''
' Returns an indication for the ability to write to the file stream.
'
' @return An indication for being able to write to the file stream.
Public Property Get CanWrite() As Boolean
CanWrite = (mCanWrite And mIsOpen)
End Property
''
' Returns an indication for the ability to seek within the file stream.
'
' @return An indication for being able to seek within the file stream.
'
Public Property Get CanSeek() As Boolean
CanSeek = (mCanSeek And mIsOpen)
End Property
''
' Returns the handle to the underlying stream.
'
' @return The handle for the underlying stream.
' @remarks If there is any information in the buffers, they are flushed
' back to the underlying stream before the handle is returned.
'
Public Property Get Handle() As Long
If mCanWrite Then Call Flush
mReadPosition = 0
mBytesBuffered = 0
Handle = mHandle
End Property
''
' Locks a portion of a file to prevent write access for other processes.
'
' @param Position The starting position in the file to begin locking.
' @param Length The number of bytes to be locked.
' @remarks Onces a section of the file is locked, read access is still allowed to other processes.
'
Public Sub LockStream(ByVal Position As Currency, ByVal Length As Currency)
Call VerifyIsOpen
Position = Int(Position)
If Position < 0@ Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "Position", Position)
Length = Int(Length)
If Length < 0@ Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "Length", Length)
Dim pos As DLong
AsCurr(pos) = CCur(0.0001@ * Position)
With AsDLong(CCur(0.0001@ * Length))
If LockFile(mHandle, pos.LoDWord, pos.HiDWord, .LoDWord, .HiDWord) = BOOL_FALSE Then IOError Err.LastDllError
End With
End Sub
''
' Unlocks a portion of the file to allow write access to the stream for other processes.
'
' @param Position The starting position in the file to begin unlocking.
' @param Length The number of bytes to be unlocked.
'
Public Sub UnlockStream(ByVal Position As Currency, ByVal Length As Currency)
Call VerifyIsOpen
Position = Int(Position)
If Position < 0@ Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "Position", Position)
Length = Int(Length)
If Length < 0@ Then _
Throw Cor.NewArgumentOutOfRangeException(Environment.GetResourceString(ArgumentOutOfRange_NeedNonNegNum), "Length", Length)
Dim pos As DLong
AsCurr(pos) = CCur(0.0001@ * Position)
With AsDLong(CCur(0.0001@ * Length))
If UnlockFile(mHandle, pos.LoDWord, pos.HiDWord, .LoDWord, .HiDWord) = BOOL_FALSE Then IOError Err.LastDllError
End With
End Sub
''
' The length of the current stream in bytes.
'
' @return The number of bytes the current file is.
' @remarks If there is write data in the buffer, it will be
' flushed out to the file to allow for an accurate reading.
'
Public Property Get Length() As Currency
Call VerifyCanSeek
Call VerifyIsOpen
If mCanWrite Then Call Flush
Dim Size As DLong
With Size
.LoDWord = GetFileSize(mHandle, .HiDWord)
' in order to catch an error we check the return value against
' INVALID_FILE_SIZE (&HFFFFFFFF). Even though it is a value
' of -1, the value must be treated as unsigned, so its negative
' values are = 2gig to 4gig positive values, which works with the
' 64bit file lengths. So, if we get the -1, we need to check for
' an actual error using Err.LastDllError.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -