2008-08-03 經驗小品 (7) VB8 下的字串與陣列轉換
黎煥欣 Li Huan Hsin
在 VB8 下(過往也有同樣的問題, 不過寫寫一些 "低階" 副程式或 "API" 就都解決了) 標榜所有的功能它都有內建. 所以以前有關字串與陣列, 與陣列之間的型態互換. 都有對應的程式. 這在一般的 VB8 (VB2005) 的書上可是看不到的..... 總之, 看了很久的 Help , 總算得到一些心得...
在 VB8 中有關 I/O 的部份, 包括 RS232/filestream/TCPIP, 若要使用它們的高效能程式, 基底操作函式都是 byte 陣列運作的. 下面是幾個範例:
-----------------------------------------------------------------------------------------------------------
serial-port
me.comPort.Read (byteArray, StartIndex, Length)
me.comPort.Write(byteArray, StartIndex, Length)
-------------------------------
file I/O
My.Computer.FileSystem.WriteAllBytes(fo$, wh, True)
byteArray = My.Computer.FileSystem.ReadAllBytes(fo$)
------------------------------------
TCP/IP (Network) -> 先建立連線, 然後指定這個連線到一個 stream resource <-實在有些嗎囉嗉
rlen = tcpStream.Read(byteArray, 0, 1024)
Me.tcpStream.Write(ByteArray, 0, 128)
--------------------------------------------------------------------------------
而且還沒別的型別可選, 就是要使用者用 byte array 來操作. 可是程式中真正使用的型別大多是別種型別, 尤其是字串 (VB8 又把字串當成一種特別的資料型式, 不是單純的陣列, 搞得更複雜). 又是看了好久的 Help, 總算得到下面的幾個函式可以 "有效" , "快速" 的做這些動作.
首先, 程式一開始要引入一堆 NameSpace (命名空間), 把這些功能通通宣告進來....
以後的程式, 不管有用沒用, 拿進來就是了
Imports System.Array <- 陣列操作
Imports System.BitConverter <- 位元組與單一型別互換操作
Imports System.Buffer <- 記憶體區塊操作
Imports System.Convert <- 轉換操作
Imports System <- system 操作
Imports System.Text <- 字串操作
Imports System.Net <- 網路操作
Imports System.Net.Sockets <- Socket 基底網路操作
Imports System.Net.NetworkInformation <- 網路訊息操作
Imports System.Threading <- 多執行緒執操作
Imports System.IO.Ports <- 自定 serial port 操作
----------------------------------------------------------------------------------------------------------------------
除了上面所提的 serial port, file, network 的操作範例. 下面有幾個可能常用到的寫法
---------------------------------------------------------------------------------------------------------------------
陣列彼此操作 (注意 "字串" 不算 system array, 它獨自成一型)
Array.Clear(AnyTypeArray, startIndex, count) <- 選定的陣列, 由起點開始清除幾個, 快速大量的清除陣列的內容
Array.Copy(SrcArray, DstArray, 10) <- 快速複製陣列, 若 SrcArray 與 DstArray 為不同型別, 會自動做轉換型的動作. (整數 -> 浮點...)
Array.Copy(a, 10, b, 10, 12) <- 複製陣列的多功能版
FindPos = Array.IndexOf(SearchArray, Value, startIndex) <- 由 Start Index 的地方快速尋找有否 value 的存在.
Array.Sort(SortArray) <- 對一個陣列內容排序
------------------------------------------------------------------------------------------------------------------
型態轉換
int32V = BitConverter.ToInt32( ByteArray, startIndex) <- 位元組陣列到單一其它型別變數的轉換, 後面的 .To XXX 可以轉換成大部份的型別.
ByteArray = System.Text.Encoding.ASCII.GetBytes(SrcString$) <- 將字串以 ASCII 編碼方式轉成位元陣列. 當然這只能轉英文字串, 中文要用別的代碼. (Unicode 或 UTF-16...), 要注意的是傳回的 ByteArray 的陣列大小會被設定成與 SrcString$ 的長度一樣, 不管它原來定義是多少個. 如
Dim bt(31) as Byte
src$="Hello"
bt = System.Text.Encoding.ASCII.GetBytes(src$)
則 bt 陣列就會只留下 5 個元素, 就如 redim bt(4) 的效果相當....
反向的函式為
dst$ = System.Text.Encoding.ASCII.GetString (bt)
若這兩行同時寫, 則 dst$ = "Hello"
---------------------------------------------------------------------------------
當我們的兩個不同型別的陣列, 要做內容的傳送. 如
int32 array -> byte array -> 網路 -> byte array -> int32 array
這個轉型用 for next 就很麻煩並且很慢, 用記憶體型式的操作是最自然的, VB8 提供了 buffer 類別的操作, 如下面的函式.
Buffer.BlockCopy(srcArray, StartIndex, dstArray,dstIndex, CountByBytes) <- 複製一段記憶體, 其中的 index 及 count 都是以 byte 來計算的. 所以當中的型別變化與內容, 就自己要知道了.....
------------------------------------------------------------------------------------------------------------------------
上面的函式總表列
Imports System.Array <- 陣列操作
Imports System.BitConverter <- 位元組與單一型別互換操作
Imports System.Buffer <- 記憶體區塊操作
Imports System.Convert <- 轉換操作
Imports System <- system 操作
Imports System.Text <- 字串操作
Imports System.Net <- 網路操作
Imports System.Net.Sockets <- Socket 基底網路操作
Imports System.Net.NetworkInformation <- 網路訊息操作
Imports System.Threading <- 多執行緒執操作
Imports System.IO.Ports <- 自定 serial port 操作
-------------------------------------------------------------------------------------------------------------------------------------
Array.Clear(AnyTypeArray, startIndex, count)
Array.Copy(SrcArray, DstArray, 10)
Array.Copy(a, 10, b, 10, 12)
FindPos = Array.IndexOf(SearchArray, Value, startIndex)
Array.Sort(SortedArray)
int32V = BitConverter.ToInt32( ByteArray, startIndex)
ByteArray = System.Text.Encoding.ASCII.GetBytes(SrcString$)
dst$ = System.Text.Encoding.ASCII.GetString (bt)
Buffer.BlockCopy(srcArray, StartIndex, dstArray,dstIndex, CountByBytes)