这里有两个需要注意的地方,ReDim Preserve bytData(1 To LenFile),下标是从1开始的,如果你写成ReDim bytData( LenFile),下标就是从0开始了,数组就有LenFile+1长了。LenFile = LOF(FreeFile)中的LOF是获得文件长度的函数,是VB里带的,很多例子用API,或者循环的读直到末尾来获取文件长度,这样都是很麻烦的,使用LOF函数就可以了。
这样的程序,即可以传送文本文件,也可以传送二进制文件。但是你有没有发现这个程序的问题呢?如果要传送一个50M的文件呢?系统可以为bytData分配50M的内存空间吗?
50M的文件做实验吧,接收到的文件和原来的文件不一样,比原来的大。问题出在那呢?
首先,根据文件大小重新定义bytData数组的大小本身就有问题,系统是不可能无限制的给数组分配空间的,即使可以,也会造成系统响应变慢。在传50M文件的时候,系统就跟死机了一样。那么怎么解决这个问题呢,一个自然的想法就是把数据分段传送。程序如下:
发送程序, iPos是个全局变量,初始值为0。这个变量保存着当前数据的位置。Const iMax = 65535是每个数据块的大小。
Dim FreeF As Integer \’空闲的文件号
Dim LenFile As Long \’文件的长度
Dim bytData() As Byte \’存放数据的数组
FreeF = FreeFile \’获得空闲的文件号
Open FileName For Binary As #FreeF \’打开文件
DoEvents
LenFile = LOF(FreeF) \’获得文件长度
If LenFile <= iMax Then \’如果要发送的文件小于数据块大小,直接发送
ReDim bytData(1 To LenFile) \’根据文件长度重新定义数组大小
Get #FreeF, , bytData \’把文件读入到数组里
Close #FreeF \’关闭文件
WinS.SendData bytData \’发送数据
Exit Sub
End If
\’文件大于数据块大小,进行分块发送
Do Until (iPos >= (LenFile - iMax)) \’发送整块数据的循环
ReDim bytData(1 To iMax)
Get #FreeF, iPos + 1, bytData
WinS.SendData bytData
iPos = iPos + iMax \’移动iPos,使它指向下来要读的数据
Loop
\’这里要注意的是,必须检查文件有没有剩下的数据,如果文件大小正好等于数据块大小的
\’ 整数倍,那么就没有剩下的数据了
ReDim bytData(1 To LenFile - iPos) \’发送剩下的不够一个数据块的数据
Get #FreeF, iPos + 1, bytData
WinS.SendData bytData
Close #FreeF
下面是接收端的程序:
Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim bytData() As Byte
责任编辑:小草