全面分析VB.NET文件传送

开发 后端
文件虽然可以传,但是接受的文件和发送的不一样,原因可能是二进制文件里可以有任何\"字符\",但是不是所有的字符都可以放在String变量里。文章介绍VB.NET文件传送的代码。

邮递员就是传递人员,那在网络上怎么传递文件的呢?这里和大家介绍一下吧。VB.NET文件传送对于网络编程来说是基本的功能,比如远程控制软件。在编制一个软件时,我从网上下了很多传文件的程序,这些程序提供的传文件功能根本就不能用。传文本还可以,传二进制文件根本就不行。因此,作为一个基本的功能模块,有必要单独介绍一下。首先,VB.NET文件传送字符串,你可以这样写:

  1. Dim strData As String  
  2. strData = \"Test\"  
  3. Winsock1.SendData strData 

但是如果你传送的二进制文件,你还能用String变量来存放吗?从理论上分析是不行的,我也做了实验,确实是不行的。文件虽然可以传,但是接受的文件和发送的不一样,原因可能是二进制文件里可以有任何\"字符\",但是不是所有的字符都可以放在String变量里。
除了String类型的变量,VB中其他类型的变量都只有几个字节长,难道一次只能发几个字节吗?那样岂不是要累死机器了!其实,情况没有那么悲观,我们完全可以使用数组来解决这个问题,就是使用byte数组。把要VB.NET文件传送都读到数组里,然后发送出去。程序如下:

FileName 为要传送的文件名,WinS为发送文件的WinSock控件。这是一个发送端的程序。

  1. Public Sub SendFile(FileName As String, WinS As Winsock)  
  2. Dim FreeF As Integer \'空闲的文件号  
  3. Dim LenFile As Long \'文件的长度  
  4. Dim bytData() As Byte \'存放数据的数组  
  5. FreeF = FreeFile \'获得空闲的文件号  
  6. Open FileName For Binary As #FreeFile \'打开文件   
  7. DoEvents   
  8.  
  9. LenFile = LOF(FreeFile) \'获得文件长度  
  10. ReDim bytData(1 To LenFile) \'根据文件长度重新定义数组大小  
  11. Get #FreeFile, , bytData \'把文件读入到数组里  
  12. Close #FreeFile \'关闭文件  
  13. WinS.SendData bytData \'发送数据  
  14. End Sub  

接受端的程序如下:

  1. Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)  
  2. Dim bytData() As Byte  
  3. Dim f  
  4. f = FreeFile 
  5. Open strFileName For Binary As #f  
  6. ReDim bytData(1 To bytesTotal)  
  7. Winsock1.GetData bytData  
  8. Put #f, i, bytData  
  9. ii = i + bytesTotal \'保证每次写都是在文件的末尾, i是个全局变量  
  10. Close #f  
  11. End Sub 

这里有两个需要注意的地方,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是每个数据块的大小。

  1. Dim FreeF As Integer \'空闲的文件号  
  2. Dim LenFile As Long \'文件的长度  
  3. Dim bytData() As Byte \'存放数据的数组  
  4. FreeF = FreeFile \'获得空闲的文件号  
  5. Open FileName For Binary As #FreeF \'打开文件  
  6. DoEvents  
  7. LenFile = LOF(FreeF) \'获得文件长度  
  8. If LenFile <= iMax Then \'如果要发送的文件小于数据块大小,直接发送  
  9. ReDim bytData(1 To LenFile) \'根据文件长度重新定义数组大小  
  10. Get #FreeF, , bytData \'把文件读入到数组里  
  11. Close #FreeF \'关闭文件  
  12. WinS.SendData bytData \'发送数据  
  13. Exit Sub  
  14. End If  
  15. \'文件大于数据块大小,进行分块发送  
  16. Do Until (iPos >= (LenFile - iMax)) \'发送整块数据的循环  
  17. ReDim bytData(1 To iMax)  
  18. Get #FreeF, iPos + 1, bytData  
  19. WinS.SendData bytData  
  20. iPosiPos = iPos + iMax \'移动iPos,使它指向下来要读的数据  
  21. Loop  
  22. \'这里要注意的是,必须检查文件有没有剩下的数据,如果文件大小正好等于数据块大小的  
  23. \' 整数倍,那么就没有剩下的数据了  
  24. ReDim bytData(1 To LenFile - iPos) \'发送剩下的不够一个数据块的数据  
  25. Get #FreeF, iPos + 1, bytData  
  26. WinS.SendData bytData  
  27. Close #FreeF 

下面是接收端的程序:

  1. Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)  
  2. Dim bytData() As Byte[Page]  
  3. Dim lLenFile As Long  
  4. Dim f  
  5. f = FreeFile 
  6. Open strFileName For Binary As #f \'strFileName是文件名  
  7. lLenFile = LOF(f)  
  8. ReDim bytData(1 To bytesTotal)  
  9. Winsock1.GetData bytData  
  10. If lLenFile = 0 Then \'lLenFile=0表示是第一次打开文件,这里有个问题,就是\'如果如果该文件存在的话,就会出错,应该在打开前检查文件是否存在。(这里我省略了)  
  11. Put #f, 1, bytData  
  12. Else  
  13. Put #f, lLenFile + 1, bytData  
  14. End If  
  15. Close #f  
  16. End Sub 

【编辑推荐】

  1. 代码讲述VB.NET实现数据绑定
  2. VB.NET TextBox组件高手经验谈
  3. 瞬间掌握VB.NET Web Service
  4. 实例分析VB.NET Treeview结构
  5. 百宝箱之VB.NET设计制作窗体
责任编辑:田树 来源: 博客
相关推荐

2009-10-28 10:04:53

VB.NET XmlW

2009-11-02 15:57:36

VB.NET WEB

2009-10-14 15:20:21

VB.NET窗体指针

2009-11-04 10:54:53

VB.NET MOVE

2009-10-15 10:57:16

VB.NET Text

2009-10-27 09:45:03

VB.NET数组

2009-10-16 13:04:57

VB.NET字符串数组

2009-10-28 17:44:31

VB.NET语言

2009-11-02 10:53:34

VB.NET INI文

2009-11-02 14:48:45

VB.NET HOOK

2009-10-15 11:42:05

VB.Net赋值语句

2009-11-10 16:46:52

VB.NET指针应用

2009-11-02 11:13:06

VB.NET读写文件

2009-10-28 14:00:02

VB.NET文件处理

2009-10-21 09:10:52

VB.NET压缩

2009-11-02 17:12:01

VB和VB.NET

2009-10-15 15:14:54

VB.NET临时文件

2009-10-20 17:38:20

VB.NET exce

2009-11-10 16:20:25

VB.NET全局热键

2009-10-29 11:26:28

VB.NET调用Web
点赞
收藏

51CTO技术栈公众号