自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

全面分析VB.NET文件傳送

開發(fā) 后端
文件雖然可以傳,但是接受的文件和發(fā)送的不一樣,原因可能是二進(jìn)制文件里可以有任何\"字符\",但是不是所有的字符都可以放在String變量里。文章介紹VB.NET文件傳送的代碼。

郵遞員就是傳遞人員,那在網(wǎng)絡(luò)上怎么傳遞文件的呢?這里和大家介紹一下吧。VB.NET文件傳送對于網(wǎng)絡(luò)編程來說是基本的功能,比如遠(yuǎn)程控制軟件。在編制一個軟件時,我從網(wǎng)上下了很多傳文件的程序,這些程序提供的傳文件功能根本就不能用。傳文本還可以,傳二進(jìn)制文件根本就不行。因此,作為一個基本的功能模塊,有必要單獨(dú)介紹一下。首先,VB.NET文件傳送字符串,你可以這樣寫:

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

但是如果你傳送的二進(jìn)制文件,你還能用String變量來存放嗎?從理論上分析是不行的,我也做了實(shí)驗(yàn),確實(shí)是不行的。文件雖然可以傳,但是接受的文件和發(fā)送的不一樣,原因可能是二進(jìn)制文件里可以有任何\"字符\",但是不是所有的字符都可以放在String變量里。
除了String類型的變量,VB中其他類型的變量都只有幾個字節(jié)長,難道一次只能發(fā)幾個字節(jié)嗎?那樣豈不是要累死機(jī)器了!其實(shí),情況沒有那么悲觀,我們完全可以使用數(shù)組來解決這個問題,就是使用byte數(shù)組。把要VB.NET文件傳送都讀到數(shù)組里,然后發(fā)送出去。程序如下:

FileName 為要傳送的文件名,WinS為發(fā)送文件的WinSock控件。這是一個發(fā)送端的程序。

  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 \'存放數(shù)據(jù)的數(shù)組  
  5. FreeF = FreeFile \'獲得空閑的文件號  
  6. Open FileName For Binary As #FreeFile \'打開文件   
  7. DoEvents   
  8.  
  9. LenFile = LOF(FreeFile) \'獲得文件長度  
  10. ReDim bytData(1 To LenFile) \'根據(jù)文件長度重新定義數(shù)組大小  
  11. Get #FreeFile, , bytData \'把文件讀入到數(shù)組里  
  12. Close #FreeFile \'關(guān)閉文件  
  13. WinS.SendData bytData \'發(fā)送數(shù)據(jù)  
  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),下標(biāo)是從1開始的,如果你寫成ReDim bytData( LenFile),下標(biāo)就是從0開始了,數(shù)組就有LenFile+1長了。LenFile = LOF(FreeFile)中的LOF是獲得文件長度的函數(shù),是VB里帶的,我見過很多例子用API,或者循環(huán)的讀直到末尾來獲取文件長度,這樣都是很麻煩的,使用LOF函數(shù)就可以了。這樣的程序,即可以傳送文本文件,也可以傳送二進(jìn)制文件。但是你有沒有發(fā)現(xiàn)這個程序的問題呢?如果我要傳送一個50M的文件呢?系統(tǒng)可以為bytData分配50M的內(nèi)存空間嗎?于是筆者拿一個50M的文件做實(shí)驗(yàn)吧,接收到的文件和原來的文件不一樣,比原來的大。問題出在那呢?

首先,根據(jù)文件大小重新定義bytData數(shù)組的大小本身就有問題,系統(tǒng)是不可能無限制的給數(shù)組分配空間的,即使可以,也會造成系統(tǒng)響應(yīng)變慢。在傳50M文件的時候,系統(tǒng)就跟死機(jī)了一樣。那么怎么解決這個問題呢,一個自然的想法就是把數(shù)據(jù)分段傳送。程序如下:發(fā)送程序, iPos是個全局變量,初始值為0。這個變量保存著當(dāng)前數(shù)據(jù)的位置。Const iMax = 65535是每個數(shù)據(jù)塊的大小。

  1. Dim FreeF As Integer \'空閑的文件號  
  2. Dim LenFile As Long \'文件的長度  
  3. Dim bytData() As Byte \'存放數(shù)據(jù)的數(shù)組  
  4. FreeF = FreeFile \'獲得空閑的文件號  
  5. Open FileName For Binary As #FreeF \'打開文件  
  6. DoEvents  
  7. LenFile = LOF(FreeF) \'獲得文件長度  
  8. If LenFile <= iMax Then \'如果要發(fā)送的文件小于數(shù)據(jù)塊大小,直接發(fā)送  
  9. ReDim bytData(1 To LenFile) \'根據(jù)文件長度重新定義數(shù)組大小  
  10. Get #FreeF, , bytData \'把文件讀入到數(shù)組里  
  11. Close #FreeF \'關(guān)閉文件  
  12. WinS.SendData bytData \'發(fā)送數(shù)據(jù)  
  13. Exit Sub  
  14. End If  
  15. \'文件大于數(shù)據(jù)塊大小,進(jìn)行分塊發(fā)送  
  16. Do Until (iPos >= (LenFile - iMax)) \'發(fā)送整塊數(shù)據(jù)的循環(huán)  
  17. ReDim bytData(1 To iMax)  
  18. Get #FreeF, iPos + 1, bytData  
  19. WinS.SendData bytData  
  20. iPosiPos = iPos + iMax \'移動iPos,使它指向下來要讀的數(shù)據(jù)  
  21. Loop  
  22. \'這里要注意的是,必須檢查文件有沒有剩下的數(shù)據(jù),如果文件大小正好等于數(shù)據(jù)塊大小的  
  23. \' 整數(shù)倍,那么就沒有剩下的數(shù)據(jù)了  
  24. ReDim bytData(1 To LenFile - iPos) \'發(fā)送剩下的不夠一個數(shù)據(jù)塊的數(shù)據(jù)  
  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表示是第一次打開文件,這里有個問題,就是\'如果如果該文件存在的話,就會出錯,應(yīng)該在打開前檢查文件是否存在。(這里我省略了)  
  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實(shí)現(xiàn)數(shù)據(jù)綁定
  2. VB.NET TextBox組件高手經(jīng)驗(yàn)談
  3. 瞬間掌握VB.NET Web Service
  4. 實(shí)例分析VB.NET Treeview結(jié)構(gòu)
  5. 百寶箱之VB.NET設(shè)計制作窗體
責(zé)任編輯:田樹 來源: 博客
相關(guān)推薦

2009-10-28 10:04:53

VB.NET XmlW

2009-11-02 15:57:36

VB.NET WEB

2009-10-15 10:57:16

VB.NET Text

2009-10-14 15:20:21

VB.NET窗體指針

2009-11-04 10:54:53

VB.NET MOVE

2009-10-27 09:45:03

VB.NET數(shù)組

2009-10-16 13:04:57

VB.NET字符串?dāng)?shù)組

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-11-10 16:46:52

VB.NET指針應(yīng)用

2009-10-15 11:42:05

VB.Net賦值語句

2009-11-02 11:13:06

VB.NET讀寫文件

2009-10-28 14:00:02

VB.NET文件處理

2009-11-02 17:12:01

VB和VB.NET

2009-10-21 09:10:52

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調(diào)用Web
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號