2022年的 Tcl/Tk 編程入門參考 10.通道基礎(chǔ)
Tcl和一些語(yǔ)言都有"通道"概念,通道就像上網(wǎng)下載文件一樣,在下載的過程之中,我們跟網(wǎng)站之間就建立了一個(gè)通道。同樣的,當(dāng)我們打開電腦上一個(gè)比較大的文件時(shí),不是一次性就讀取完畢的,它也是一部分一部分讀取,就像網(wǎng)絡(luò)下載一樣。所以TCL語(yǔ)言里,文件的讀寫和網(wǎng)絡(luò)的收發(fā),都被歸結(jié)為“通道”這樣一個(gè)概念,部分命令是通用的。
我查了一下,TCL剛流行的那個(gè)年代,內(nèi)存大概在4MB~8MB左右。當(dāng)時(shí)內(nèi)存還沒有現(xiàn)在網(wǎng)絡(luò)帶寬大,所以那個(gè)時(shí)候,讀取一個(gè)稍微大一點(diǎn)的文件,就跟現(xiàn)在從網(wǎng)上下一個(gè)文件差不多。所以TCL語(yǔ)言能把文件系統(tǒng)和網(wǎng)絡(luò)系統(tǒng),歸結(jié)為一個(gè)“通道”的概念,也是有歷史原因的。
管道
Tcl的通道跟Unix/Linux系統(tǒng)常見的"管道"不是一個(gè)概念。命令管道常用于Unix和linux操作系統(tǒng),在windows里也支持。"管道"是一種機(jī)制,用于把命令的內(nèi)容傳遞給其它命令,以便進(jìn)一步做操作。
Tcl的通道中也包含對(duì)命令管道的支持,下面open命令會(huì)介紹。
open
Open命令的作用是打開一個(gè)通道,它用于文件、命令管道以及串行通信端口。串行通信端口,在Windows上就是COM端口(俗稱串口),一般用COM+數(shù)字表示,比如COM1、COM2……對(duì)于COM設(shè)備,我手上沒有,所以沒法測(cè)試。我記得以前刷卡的設(shè)備和超市收銀小票的打印機(jī),都是串口的,現(xiàn)在是什么接口我就不清楚了。然后open命令的文檔里,大約一半的內(nèi)容都是串行通信端口相關(guān)的功能,這部分,只能說是有需要的朋友自行研究了。
Open命令可以通過存取權(quán)限參數(shù)來控制通道的讀寫權(quán)限,默認(rèn)的情況下是只讀。存取權(quán)限有兩種設(shè)定方式,第一種是通過R、W、A這三個(gè)字母來進(jìn)行設(shè)定。

第二種方式,是通過一些詞匯來組合成列表來進(jìn)行設(shè)定,也就是下面圖片顯示的這些,在這里詞匯里,第一行的只讀、只寫、讀寫這三個(gè)詞匯必須有一個(gè)。這里的非阻塞模式這個(gè)詞匯,官方不建議使用。然后最下面的TTY終端文件這個(gè)標(biāo)志,是用于Unix和Linux操作系統(tǒng)的,作用就是把終端文件這種特殊的文件當(dāng)成文件來看待,而不是當(dāng)成終端。

接下來通過例子看一下:
?
第一個(gè)例子是命令管道,這里我用了open命令打開了一個(gè)命令管道的通道。這里以 | 豎線開頭,后面跟命令(可以帶空格也可以省略空格),然后通過open命令打開的通道,我們就能讀取命令的內(nèi)容(對(duì)于部分特殊的命令,也可以通過通道發(fā)送內(nèi)容)。在這個(gè)例子里,就是讀取了whoami命令返回的用戶名。
另:whoami命令是信息安全行業(yè)的一個(gè)經(jīng)典命令,因?yàn)檫@個(gè)命令在服務(wù)器操作系統(tǒng)里幾乎都有,不僅僅是linux,win2000、2003、2008這種操作系統(tǒng),就連小型機(jī)的操作系統(tǒng)里也有這個(gè)命令。所以用這個(gè)命令,可以驗(yàn)證是否已經(jīng)取得了執(zhí)行命令的權(quán)限、以及當(dāng)前用戶是什么。
后面兩個(gè)例子是文件的例子,分別使用了兩種存取權(quán)限設(shè)置方式。
read
read命令讀取通道內(nèi)容,默認(rèn)情況下讀取全部?jī)?nèi)容。使用-nonewline參數(shù),丟棄末尾換行。
還可以指定每次讀取的字符數(shù)量,無論什么語(yǔ)言都會(huì)讀取設(shè)定的字符數(shù)量(不是字節(jié)量)。比如,設(shè)定50個(gè)字符,英文就讀取50個(gè)字母,中文就讀取50個(gè)漢字。這里要提醒的是,一個(gè)漢字至少占用兩個(gè)字節(jié),所以無論是文件通道還是網(wǎng)絡(luò)通道,這個(gè)命令每次的"吞吐量"很可能是不一樣的。另外read會(huì)記錄每次讀完的位置(就像打字時(shí),代表錄入位置的光標(biāo)一樣),如果再次運(yùn)行,它就會(huì)繼續(xù)讀取后續(xù)的內(nèi)容。
我們?cè)谶@個(gè)例子里面,以Windows系統(tǒng)自帶的arp命令為例,大家可以先在命令提示符或者powershell里面,運(yùn)行一下arp命令,不帶參數(shù)的話,顯示就是這個(gè)命令的說明。然后例子里第一次讀取前20個(gè)字符,我們?cè)俅芜\(yùn)行這條語(yǔ)句,它就會(huì)繼續(xù)讀取20個(gè)字符,也就是從21開始到40為止的字符。這樣可以實(shí)現(xiàn)遞進(jìn)式的讀取文件內(nèi)容。這個(gè)功能除了一些特殊需求之外,主要用于處理大文件。此外要說的是,換行符和空格等特殊字符都會(huì)被算做字符,所以在設(shè)定的時(shí)候,要注意特殊字符的問題。
puts
puts命令:向通道內(nèi)寫入信息。之前使用puts命令時(shí)都是拿它當(dāng)顯示命令用,因?yàn)樵诓恢付ㄍǖ罆r(shí),默認(rèn)為 stdout 即標(biāo)準(zhǔn)輸出通道。該命令完整用法為:
puts ?-nonewline? ?通道ID? 字符串(要寫入的信息)
close
close命令,關(guān)閉通道。默認(rèn)情況下,會(huì)完整的關(guān)閉通道。在用于網(wǎng)絡(luò)通道或管道命令通道時(shí),可以只關(guān)閉一半的通道,就是說把讀取或者寫入關(guān)閉,這種狀態(tài)稱之為“半關(guān)閉”,半關(guān)閉我在網(wǎng)絡(luò)部分再舉例子。
如果是敲語(yǔ)句測(cè)試的話,puts命令執(zhí)行完畢之后,我們預(yù)計(jì)的是內(nèi)容已經(jīng)寫入到文件里了,但打開文件的話,很大可能還是空白的。這是因?yàn)門CL語(yǔ)言有個(gè)緩沖機(jī)制(見flush命令),在執(zhí)行關(guān)閉操作的時(shí)候,緩沖區(qū)內(nèi)容都會(huì)寫入文件,所以執(zhí)行完close命令,文件里面就有內(nèi)容。
flush
flush 命令:立刻處理緩沖區(qū)的內(nèi)容。TCL語(yǔ)言緩沖機(jī)制:數(shù)據(jù)積攢到一定數(shù)量才會(huì)寫入到文件中,這么做可以防止頻繁讀寫存儲(chǔ)系統(tǒng)。以下例子請(qǐng)?jiān)?tclsh 或 wish 中手動(dòng)輸入語(yǔ)句測(cè)試:
gets
gets 命令:每次運(yùn)行都讀取通道內(nèi)一行的內(nèi)容。讀取后會(huì)記錄位置,跟read命令類似,在部分情況下更人性化,以換行作為每次讀取量的標(biāo)準(zhǔn)。默認(rèn)返回本次讀取的內(nèi)容。
gets 通道ID ?變量名?
變量名參數(shù)是可選的,如果設(shè)定了變量名,則gets命令改為返回本次讀取的字符數(shù),并將讀取的內(nèi)容保存在變量里。
eof
eof 命令:驗(yàn)證通道是否還有內(nèi)容,即否已經(jīng)讀取結(jié)束:結(jié)束,返回1;未結(jié)束,返回0
2022年的 Tcl/Tk 編程入門參考 10.通道基礎(chǔ)的評(píng)論 (共 條)
