?
https://code.google.com/p/cliche/ ? ? ?jar 包 見附件
?
?
jline ? jar ?,好像是 ?hive ?的命令行 也使用了, http://jline.sourceforge.net
?
以下是引用別人的信息:
Overview
????? JLine 是一個用來處理控制臺輸入的Java類庫,目前最新的版本是0.9.94。其官方網址是http://jline.sourceforge.net。在介紹JLine之前,首先還是介紹一下Java 6中的Console類,以便進行對比。
?
2 Java Console
?? ?? 通過調用System.console()方法可以得到與當前虛擬機對應的Console對象。但是該方法并不保證其返回值一定非null,這取決于底層平臺和虛擬機啟動的方式:如果是通過交互式的命令行啟動,并且標準輸入和輸出流沒有被重定向,那么該方法的返回值通常是非null;如果是被自動啟動(例如cron)或者通過Eclipse啟動,那么返回值通常為null。
????? Console類支持的功能有限,其中一個比較有用的功能是以非回顯(echo)的方式從控制臺讀取密碼。
?
3 JLine
????? JLine不依賴任何core Java以外的類庫,但是其不是純Java的實現。
- 在Windows平臺下,JLine通過自帶的.dll文件初始化終端。jline.jar中包含了jline32.dll和jline64.dll,在Windows平臺上使用的時候, JLine會自動將其解壓縮到臨時目錄并進行加載。
- 在Unix或者Max OS X平臺下,JLine通過stty命令初始化終端。例如通過調用stty -icanon min 1將控制臺設置為character-buffered模式。以及通過調用stty -echo禁止控制臺回顯。在修改終端的屬性之前,JLine會對終端的屬性進行備份,然后注冊一個ShutdownHook,以便在程序退出時進行恢復。由于JVM在非正常退出時(例如收到SIGKILL信號)不保證ShutdownHook一定會被調用,因此終端的屬性可能無法恢復。
????? JLine使用起來非常簡單,jline.jar中一共只有20幾個類,源碼也不難懂。以下是個簡單的例子,其中readLine函數的參數指定了命令行提示符:
- ConsoleReader?reader?=? new ?ConsoleReader();??
- String?line?=?reader.readLine( ">" );??
?
3.1 Features
3.1.1 Command History
????? 通過按下鍵盤的上下箭頭鍵,可以瀏覽輸入的歷史數據。此外JLine也支持終端快捷鍵,例如Ctrl+A, Ctrl+W,Ctrl+K, Ctrl+L等等,使用的時候非常便捷。
????? 可以通過ConsoleReader的setUseHistory(boolean useHistory)方法啟用/禁用Command History功能。ConsoleReader的history成員變量負責保存歷史數據,默認情況下歷史數據只保存在內存中。如果希望將歷史數據保存到文件中,那么只需要以File對象作為參數構造History對象,并將該History對象設置到ConsoleReader即可。
3.1.2 Character Masking
????? ConsoleReader提供了一個readLine(final Character mask) 方法,用來指定character mask。如果參數為null,那么輸入的字符正常回顯;如果為0,那么不回顯;否則回顯mask指定的字符。
3.1.3 Tab Completion
????? JLine中跟自動補全相關的接口是Completor,它有以下幾個實現:
- SimpleCompletor: 對一系列指定的字符串進行自動補全。
- FileNameCompletor: 類似于bash中的文件名自動補全。
- ClassNameCompletor: 對classpath中出現的全路徑類名進自動補全。
- NullCompletor: 不進行自動補全。
- ArgumentCompletor: 為每個屬性使用指定的Completor。
????? 以下是個簡單的例子:
- ConsoleReader?reader?=? new ?ConsoleReader();??
- List<Completor>?completors?=? new ?ArrayList<Completor>();??
- completors.add( new ?SimpleCompletor( new ?String[]{ "abc" ,? "def" }));??
- completors.add( new ?FileNameCompletor());??
- completors.add( new ?ClassNameCompletor());??
- completors.add( new ?NullCompletor());??
- reader.addCompletor( new ?ArgumentCompletor(completors));??
- reader.readLine( ">" );??
????? 以上例子中首先在命令行上鍵入a,然后按下TAB后會自動補全第一個屬性abc;然后鍵入空格,再按下TAB會進行文件名的自動補全;再鍵入空格和按下TAB后會進行類名的自動補全; 再鍵入空格和按下TAB后不再有自動補全。需要注意的是,ArgumentCompletor會對命令行上所有索引超過completors長度的屬性使用completors中最后一個元素指定的Completor。如果要禁用這個行為,那么將completors的最后一個元素設置為NullCompletor對象。
?
3.1.4 Custom Keybindings
????? 通過創建 HOME/.jlinebindings.properties文件(或者制定 jline.keybindings 系統變量),可以定制keybindings。
?
4 Known Issues
????? JLine最知名的問題莫過于在Windows平臺下的Eclipse中啟動的程序中調用reader.readLine()方法時總是返回null(正確的行為是等待用戶輸入)。通過debug, 筆者發現通過設置jline.WindowsTerminal.directConsole屬性為false,可以解決返回null的問題,但是感覺還是有些其它的問題??傊?,筆者沒有發現好的對策,只能work around,即對JLine再進行一層封裝,在某些場景下仍然使用原始的基于System.in的流處理。
?
5 Usage
????? 想必很多項目都會為其應用做一層Application之類的抽象。對應用進行監控的常見方式是使用JMX,JMX從邏輯上可以認為是應用程序的一個Shell。筆者為項目中的Application提供了一套完整的Shell抽象,包括Shell、Console、 Process 和 Command等等。其中JLine是一種Console的具體實現。如果是后臺應用,那么可以通過基于Socket的Console連接到應用,從而進行監控,例如停止應用程序等。如果前臺的交互式應用,那么可以直接使用基于終端的Console實現, 例如筆者項目中為Spring Batch實現的CommandLine Scheduler等。
?
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
