分享
 
 
 

VB 二进制块读写类模块(第一版)

王朝c#·作者佚名  2006-12-17
窄屏简体版  字體: |||超大  

'CFileRead.cls-----------------------------------------------------------------------------------

Option Explicit

'***************************************************************

'读写文件的类,为文件的读写操作提供了封装,用起来更方便,重用度好

'这是读文件的类。

'刘琦。2005-3-7 Last modified.

'***************************************************************

Private m_bFileOpened As Boolean '文件打开标志

Private m_iFileNum As Integer '文件号,为什么用Integer,由FreeFile的定义得知

Private m_lFileLen As Long '文件长度

Private Declare Sub CopyMemory Lib 'kernel32' Alias _

'RtlMoveMemory' (Destination As Any, _

Source As Any, ByVal Length As Long)

Public Function OpenBinary(ByVal sFQFilename As String) As Boolean

'打开一个二进制文件,成功返回真,失败返回假

'INPUT------------------------------------------------------------

'sFQFilename 要打开文件的全路径名

'-----------------------------------------------------------------

'OUTPUT-----------------------------------------------------------

'返回值 成功返回真,失败返回假

'-----------------------------------------------------------------

'备注-------------------------------------------------------------

'该类的一个实例在同一时间只能够打开一个文件。

'-----------------------------------------------------------------

OpenBinary = False 'default Return value.

On Error GoTo catch '错误捕获

If m_bFileOpened Then Err.Raise 1000 '如果该类的实例正处在打开文件的

'状态,那么不允许打开另一个文件,引发一个错误。这意味着这个类遵循强严谨

'性编码规则,而非强容错性编码规则(按这个规则的要求,就不会报错,而是自

'动关闭上一个打开的文件)

m_iFileNum = FreeFile '取得一个合法文件号

'以二进制、只读方式打开文件

Open sFQFilename For Binary Access Read As #m_iFileNum

m_bFileOpened = True '如果能执行到这一句,说明文件打开了,记录状态

m_lFileLen = LOF(m_iFileNum) '取得文件长度

OpenBinary = True 'return succeed flag!!!

Exit Function

catch:

End Function

Public Sub CloseFile()

'关闭曾经用OpenBinary打开过的文件

If m_bFileOpened Then '如果现在正处在打开文件的状态。

'如果当前状态为有文件打开,那么关闭它,并设置当前状态

Close #m_iFileNum '关闭文件

m_bFileOpened = False '文件打开标志设为假

m_iFileNum = -1 '把文件号和文件长度设为无效值

m_lFileLen = -1

Else

'如果没有打开文件

Err.Raise 1000 '报错,这意味着这个类遵循强严谨

'性编码规则

End If

End Sub

'几个只读属性------------------------------------------

Public Property Get FileNumber() As Integer

FileNumber = m_iFileNum

End Property

Public Property Get FileOpened() As Boolean

FileOpened = m_bFileOpened

End Property

Public Property Get FileLength() As Long

FileLength = m_lFileLen

End Property

'-------------------------------------------------------

Public Function ReadBlock(ByVal lpBuffer As Long, _

ByVal lBufferSize As Long) As Long

'读文件的块,在使用此方法前需要先打开文件

'INPUT------------------------------------------------------------------------------

'lpBuffer 用来接受数据的缓冲区指针

'lBufferSize 指出缓冲区的大小(以字节计)

' (也就是期望从文件中读取的字节数)

'OUTPUT-----------------------------------------------------------------------------

'返回值 实际读取到缓冲区的字节数,可能等于也可能小于 lBufferSize

Dim lTemp As Long

Dim aBuf() As Byte

'计算出从当前文件指针开始到文件末尾还有多少字节未读

'计算方法就是文件长度减去已读的字节数,就是未读的字节数

'就是 m_lFileLen-(seek(m_ifilenum)-1)

lTemp = m_lFileLen - Seek(m_iFileNum) + 1

If lTemp >= lBufferSize Then '[lBufferSize..)

'未读字节数大于等于缓冲区大小

'可以填满缓冲区(这种情况的出现概率较大,所以放在最前)

ReadBlock = lBufferSize '返回实际读取到缓冲区的字节数

ReDim aBuf(0 To lBufferSize - 1) '分配空间,大小是lBufferSize

Get #m_iFileNum, , aBuf() '从文件中读取 lBufferSize个字节

CopyMemory ByVal lpBuffer, aBuf(0), lBufferSize

'把数据复制到客户的缓冲区

ElseIf lTemp > 0 Then '(0..lBufferSize) 也即 [1..lBufferSize-1]

' 0< lTemp < lBufferSize

'还有字节需要读,但不足以填满缓冲区

ReadBlock = lTemp '返回实际读取的字节数

ReDim aBuf(0 To lTemp - 1) '定义一个刚好能容纳将要读取数据的数组

Get #m_iFileNum, , aBuf() '读块

CopyMemory ByVal lpBuffer, aBuf(0), lTemp '投放到客户提供的缓冲区里

Else '( ..0]

'没有字节需要读了,回吧

ReadBlock = 0 '返回实际读取到缓冲区的字节数

End If

End Function

Private Sub Class_Terminate()

If m_bFileOpened Then Err.Raise 1000, , 'Please Close File'

End Sub

'---------------------------------------------------------------------------------------------------------------------------

'CFileWrite.cls--------------------------------------------------------------------------------------------------------

Option Explicit

'***************************************************************

'读写文件的类,为文件的读写操作提供了封装,用起来更方便,重用度好

'这是写文件的类。

'刘琦。2005-3-7 Last modified.

'***************************************************************

'CFileWrite--------------------------------------------------------------------------

Private m_bFileOpened As Boolean '文件打开标志

Private m_iFileNum As Integer '文件号,为什么用Integer,由FreeFile的定义得知

Private m_lFileLen As Long '文件长度

Private Declare Sub CopyMemory Lib 'kernel32' Alias _

'RtlMoveMemory' (Destination As Any, Source As Any, _

ByVal Length As Long)

Public Function OpenBinary(ByVal sFQFilename As String) As Boolean

'打开一个文件,成功返回真,失败返回假

'INPUT------------------------------------------------------------

'sFQFilename 要打开文件的全路径名

'-----------------------------------------------------------------

'OUTPUT-----------------------------------------------------------

'返回值 成功返回真,失败返回假

'-----------------------------------------------------------------

'备注-------------------------------------------------------------

'该类的一个实例在同一时间只能够打开一个文件。

'-----------------------------------------------------------------

OpenBinary = False 'default Return

On Error GoTo catch

If m_bFileOpened Then Err.Raise 1000 '如果该类的实例正处在打开文件的

'状态,那么不允许打开另一个文件,引发一个错误。这意味着这个类遵循强严谨

'性编码规则,而非强容错性编码规则(按这个规则的要求,就不会报错,而是自

'动关闭上一个打开的文件)

m_iFileNum = FreeFile '取得一个合法文件号

'以二进制、只写方式打开文件

Open sFQFilename For Binary Access Write As #m_iFileNum

m_bFileOpened = True '如果能执行到这一句,说明文件打开了,记录状态

m_lFileLen = LOF(m_iFileNum) '取得文件长度

OpenBinary = True 'return succeed flag!!!

Exit Function

catch:

End Function

Public Sub CloseFile()

'关闭曾经用OpenBinary打开过的文件

If m_bFileOpened Then '如果现在正处在打开文件的状态。

'如果当前状态为有文件打开,那么关闭它,并设置当前状态

Close #m_iFileNum '关闭文件

m_bFileOpened = False '文件打开标志设为假

m_iFileNum = -1 '把文件号和文件长度设为无效值

m_lFileLen = -1

Else

'如果没有打开文件

Err.Raise 1000 '报错,这意味着这个类遵循强严谨

'性编码规则

End If

End Sub

'只读属性------------------------------------------

Public Property Get FileNumber() As Integer

FileNumber = m_iFileNum

End Property

Public Property Get FileOpened() As Boolean

FileOpened = m_bFileOpened

End Property

Public Property Get FileLength() As Long

FileLength = m_lFileLen

End Property

'-------------------------------------------------------

Public Sub WriteBlock(ByVal lpBuffer As Long, ByVal nCount As Long)

'把一块缓冲区的数据写入到文件中,前提是文件必须打开

'INPUT--------------------------------------------------------------

'lpBuffer 数据缓冲区的指针

'nCount 期望写入的字节数

'OUTPUT-------------------------------------------------------------

'N/A

'

Dim aBuf() As Byte

If nCount <= 0 Then Exit Sub

ReDim aBuf(0 To nCount - 1) '定义一个于期望写入的字节数大小相等的数组

CopyMemory aBuf(0), ByVal lpBuffer, nCount '把客户提供的数据拷贝到aBuf()中

Put #m_iFileNum, , aBuf() '写到文件

End Sub

Private Sub Class_Terminate()

If m_bFileOpened Then Err.Raise 1000, , 'Please Close File'

End Sub

'----------------------------------------------------------------------------------------------------------------------------

'以下是使用范例-------------------------------------------------------------------------------------------------------

'form1.frm--------------------------------------------------------------------------------------------------------------

Option Explicit

Dim m_cFileRead As New CFileRead

Dim m_cFileWrite As New CFileWrite

Private Sub Command1_Click()

Const BUFFER_SIZE As Long = 4096 * 2

Dim nActual As Long

Dim aBuf(0 To BUFFER_SIZE - 1) As Byte

Dim lpBuf As Long

Dim tmr As Single

tmr = Timer

lpBuf = VarPtr(aBuf(0))

If Not m_cFileRead.OpenBinary(Text1.Text) Then MsgBox '打开文件失败!' & Text1.Text

If Not m_cFileWrite.OpenBinary(Text2.Text) Then MsgBox '打开文件失败!' & Text2.Text

Do

nActual = m_cFileRead.ReadBlock(lpBuf, BUFFER_SIZE)

m_cFileWrite.WriteBlock lpBuf, nActual

Loop Until nActual < BUFFER_SIZE '当实际读取字节数小于缓冲区大小的时候,就不需要再读啦,已读完啦

m_cFileRead.CloseFile

m_cFileWrite.CloseFile

MsgBox 'OK! total time:' & Timer - tmr

End Sub

Private Sub Command2_Click()

Const BUFFER_SIZE = 1

Dim nActual As Long

Dim aBuf(0 To BUFFER_SIZE - 1) As Byte

Dim tmr As Single

tmr = Timer

If Not m_cFileRead.OpenBinary(Text1.Text) Then MsgBox '打开文件失败!' & Text1.Text

If Not m_cFileWrite.OpenBinary(Text2.Text) Then MsgBox '打开文件失败!' & Text2.Text

Do

nActual = m_cFileRead.ReadBlock(VarPtr(aBuf(0)), BUFFER_SIZE)

m_cFileWrite.WriteBlock VarPtr(aBuf(0)), nActual

Loop Until nActual < BUFFER_SIZE '当实际读取字节数小于缓冲区大小的时候,就不需要再读啦,已读完啦

m_cFileRead.CloseFile

m_cFileWrite.CloseFile

MsgBox 'OK! total time:' & Timer - tmr

End Sub

Private Sub Command3_Click()

Const BUFFER_SIZE = 40960 * 2

Dim nActual As Long

Dim aBuf(0 To BUFFER_SIZE - 1) As Byte

Dim tmr As Single

Dim lFileLen As Long

Dim iFileNum As Integer

Dim k As Long

tmr = Timer

If Not m_cFileRead.OpenBinary(Text1.Text) Then MsgBox '打开文件失败!' & Text1.Text

If Not m_cFileWrite.OpenBinary(Text2.Text) Then MsgBox '打开文件失败!' & Text2.Text

lFileLen = m_cFileRead.FileLength

iFileNum = m_cFileRead.FileNumber

k = 0

Do

k = k + 1

If k = 10 Then

k = 0

pb1.Value = 100 * (Seek(iFileNum) / lFileLen)

DoEvents

End If

nActual = m_cFileRead.ReadBlock(VarPtr(aBuf(0)), BUFFER_SIZE)

m_cFileWrite.WriteBlock VarPtr(aBuf(0)), nActual

Loop Until nActual < BUFFER_SIZE '当实际读取字节数小于缓冲区大小的时候,就不需要再读啦,已读完啦

m_cFileRead.CloseFile

m_cFileWrite.CloseFile

MsgBox 'OK! total time:' & Timer - tmr

End Sub

Private Sub Command4_Click()

Dim sPass As String

sPass = InputBox('请输入密码。')

Dim cLogi As New CLogistic

cLogi.Pass = sPass

Const BUFFER_SIZE = 4096

Dim nActual As Long

Dim aBuf(0 To BUFFER_SIZE - 1) As Byte

Dim tmr As Single

Dim lFileLen As Long

Dim iFileNum As Integer

Dim k As Long

tmr = Timer

If Not m_cFileRead.OpenBinary(Text1.Text) Then MsgBox '打开文件失败!' & Text1.Text

If Not m_cFileWrite.OpenBinary(Text2.Text) Then MsgBox '打开文件失败!' & Text2.Text

lFileLen = m_cFileRead.FileLength

iFileNum = m_cFileRead.FileNumber

k = 0

Do

k = k + 1

If k = 10 Then

k = 0

pb1.Value = 100 * (Seek(iFileNum) / lFileLen)

DoEvents

End If

nActual = m_cFileRead.ReadBlock(VarPtr(aBuf(0)), BUFFER_SIZE)

cLogi.EncBlock aBuf, nActual

m_cFileWrite.WriteBlock VarPtr(aBuf(0)), nActual

Loop Until nActual < BUFFER_SIZE '当实际读取字节数小于缓冲区大小的时候,就不需要再读啦,已读完啦

m_cFileRead.CloseFile

m_cFileWrite.CloseFile

MsgBox 'OK! total time:' & Timer - tmr

End Sub

Private Sub Command5_Click()

If Not m_cFileRead.OpenBinary(Text1.Text) Then MsgBox '打开文件失败!' & Text1.Text

m_cFileRead.CloseFile

If Not m_cFileRead.OpenBinary(Text1.Text) Then MsgBox '打开文件失败!' & Text1.Text

m_cFileRead.CloseFile

If Not m_cFileWrite.OpenBinary(Text2.Text) Then MsgBox '打开文件失败!' & Text2.Text

m_cFileWrite.CloseFile

If Not m_cFileWrite.OpenBinary(Text2.Text) Then MsgBox '打开文件失败!' & Text2.Text

m_cFileWrite.CloseFile

End Sub

'---------------------------------------------------------------------------------------------------------------------------

'-------------------------------------------------------------------------------------------------------------------------'

完整的VB工程文件可从这里下载

http://lqweb.nease.net/mycode/FileReadBlockFileWriteBlock.zip

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有