使用内存映射文件加快文件操作速度




利用VB自身的文件处理命令,在对付几兆大小的文件时往往显得力不从心,速度慢得令人难以忍受。其实可以用一种方法将整个文件都读入内存,而不用一次又一次地访问磁盘。这个方法的实现可以通过多种方式。例如你可以将文件读入到一个Byte数组或一个字符串中,就象下面的代码一样:

Public Function GetFileBytes (FileName as String, Data() as Byte) As Boolean


Dim hFile as Long
hFile=FreeFile
On Error Resume Next
Open FileName For Binary As #hFile
Redim Data(0 To LOF(hFile)-1) As Byte
Get #hFile,,Data
Close #hFile
GetFileBytes=(Err.Number=0)

End Function

如果你的文件较小的话,上面的小程序还是小巧易用的。但随着你要处理的文件大小的增加,问题也就随之而来了。同样地,使用字符串变量不仅会加重内存的负担,还可能会因为Unicode与Ansi的转换问题而把你搞得焦头烂额。因此最好的解决办法就是使用内存映射文件。

所谓内存映射文件不过是那些文件中的数据被直接映射到你的进程地址空间中去的文件。如果你不知道你要处理的文件的格式,或是可以从文件头或类似的段中获得文件格式的话,这种方法正是你所需要的。对于同样的操作,使用内存映射文件比一般文件访问方法快20倍左右。

要创建内存映射文件,首先要使用CreateFile打开一个已存在的文件,然后调用CreateFileMapping创建一个文件映射对象。接下来将由CreateFileMapping返回的句柄传递给函数MapViewOfFile,将整修文件映射到你的地址空间中。MapViewOfFile返回一个基地址。通过计算相对于该基地址的偏移量,你就可以访问文件中的数据了。当你完成文件访问后,调用UnMapViewOfFile和CloseHandle以释放内存。你可以下载本站提供的CMapFile类模块帮你完成上面的工作。下面以这个类模块为例讲讲内存映射文件具体的使用方法。

创建了映射文件后,你就可以用CopyMemory这个API函数对文件进行读、写操作了。在进行读写操作之前,你必须知道你所要操作的数据在文件中的位置,同时你必须对数据在内存中的表现形式有一个非常清楚的了解。通常,文件都将自己的格式信息用独特的字符保存在一个固定的专访。例如,ZIP文件中的头两个字符为“PK”,下面的代码在处理文件其余部分之前是读取这两个字符。

Dim mf As New CMapFile
Dim Buffer() As Byte
mf.MapFile "C: est.zip"
Redim Buffer(0 to 1) As Byte
mf.GetRng VarPtr((Buffer(0)),0,2
Debug.Print StrConv(Buffer, vbUnicode)

CMapFile类的GetRng方法接收欲拷贝的数据所在地址的指针及欲拷贝的数据长度,将数据保存在变量中。这种方法为你提供了最大的灵活性,因为你可以将数据放入任何VB自身的数据类型。CMapFile也提供直接读取Long和Double两种类型的值的函数。

不要让指针把你吓怕了。它们只不过是一些包含了内存中某些东西的地址的长整型数而已。CMapFile通过将基地址与你所传递的今移量相加,为你自动计算出指针。你所要做的就是要找到你所需要的数据在文件中的偏移量。请注意:1。你提供的今移量应小于映射文件的大小;2。缓冲区的大小必须足够接收你要求的数据。
 
 
KiteGirl(小仙妹) 于 2005-8-14 12:00:50


Private Sub Form_Load()
Dim 局部_字节数组() As Byte

局部_字节数组() = 从文件获得字节数组("index.htm") '读文件index.htm,可以改成你自己的文本文件。

Dim 局部_文本 As String

局部_文本 = StrConv(局部_字节数组(), vbUnicode)

Dim 局部_行数组() As String

Dim 局部_换行 As String

局部_换行 = vbCrLf

局部_行数组() = Split(局部_文本, 局部_换行)

'局部_行数组()每个元素就是一行。

文字栏_输出.Text = UBound(局部_行数组())+1 '计算有多少行。

文本框_内容.Text = 局部_文本 '显示文本文件内容。"文本框_内容"的multiline属性必须为true
End Sub

Public Function 从文件获得字节数组(ByVal 参数_文件名 As String) As Byte()
Dim 局部_输出字节数组() As Byte

Dim 局部_文件号 As Integer

局部_文件号 = FreeFile

Open 参数_文件名 For Binary As #局部_文件号

Dim 局部_输出字节数组_终点 As Long
Dim 局部_文件终点 As Long

局部_文件终点 = LOF(局部_文件号)

局部_输出字节数组_终点 = 局部_文件终点 - 1

ReDim 局部_输出字节数组(局部_输出字节数组_终点)

Get #局部_文件号, 1, 局部_输出字节数组()

Close #局部_文件号

从文件获得字节数组 = 局部_输出字节数组
End Function

 

 

‘---MSDN=====

Private Sub Command1_Click()
Dim t As String
Dim w As String
Open "C:/0302.txt " For Input As #1
Do While Not EOF(1)
Line Input #1, t
w = w + t + Chr$(13) + Chr(10)
Loop
Text1.Text = w
Close #1

End Sub


 

你可能感兴趣的:(VB)